OSDN Git Service

727275f08630cb1357d13ec5f7714e39cb2fc39c
[kita/kita.git] / kita / src / kita.cpp
1 /***************************************************************************
2 *   Copyright (C) 2003 by Hideki Ikemoto                                  *
3 *   ikemo@users.sourceforge.jp                                            *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 ***************************************************************************/
10
11 #include "kita.h"
12 #include "pref.h"
13 #include "kitathreadview.h"
14 #include "kitasubjectview.h"
15 #include "kitaboardview.h"
16 #include "libkita/threadinfo.h"
17 #include "libkita/favoriteboards.h"
18 #include "kitathreadtabwidget.h"
19 #include "kitasubjecttabwidget.h"
20 #include "kitanavi.h"
21
22 #include "libkita/thread.h"
23 #include "libkita/favoritethreads.h"
24 #include "libkita/kita_misc.h"
25 #include "libkita/kitaconfig.h"
26 #include "libkita/signalcollection.h"
27 #include "libkita/parsemisc.h"
28
29 #include <qdragobject.h>
30 #include <qtextcodec.h>
31 #include <qevent.h>
32
33 #include <klineedit.h>
34 #include <kglobal.h>
35 #include <klocale.h>
36 #include <kiconloader.h>
37 #include <kmenubar.h>
38 #include <kstatusbar.h>
39 #include <kkeydialog.h>
40 #include <kaccel.h>
41 #include <kio/netaccess.h>
42 #include <kuserprofile.h>
43 #include <kfiledialog.h>
44 #include <kconfig.h>
45 #include <kurl.h>
46 #include <krun.h>
47 #include <kstandarddirs.h>
48 #include <kdebug.h>
49 #include <ksimpleconfig.h>
50 #include <kedittoolbar.h>
51 #include <kstdaccel.h>
52 #include <kaction.h>
53 #include <kstdaction.h>
54 #include <kshortcut.h>
55 #include <kaboutdata.h>
56 #include <kparts/partmanager.h>
57
58 KitaMainWindow::KitaMainWindow()
59         : KParts::DockMainWindow( 0, "Kita" ),
60         m_printer( 0 )
61 {
62     // accept dnd
63     setAcceptDrops( true );
64
65     // setup view, dock
66     setupView();
67
68     // then, setup our actions
69     setupActions();
70
71     // load cache
72     loadCache();
73
74     // load favorites
75     loadFavorites();
76
77     // load favorite boards;
78     loadFavoriteBoards();
79
80     // load completion
81     loadCompletion();
82
83     // load ascii art
84     loadAsciiArt();
85
86     // load abone lists
87     loadAboneIDList();
88     loadAboneNameList();
89     loadAboneWordList();
90
91     // and a status bar
92     statusBar() ->show();
93
94     readDockConfig( KGlobal::config() );
95
96     readConfig( KGlobal::config() );
97
98     // apply the saved mainwindow settings, if any, and ask the mainwindow
99     // to automatically save settings if changed: window size, toolbar
100     // position, icon size, etc.
101     setAutoSaveSettings();
102
103     // allow the view to change the statusbar and caption
104     Kita::SignalCollection* signalCollection = Kita::SignalCollection::getInstance();
105     connect( signalCollection, SIGNAL( signalChangeStatusbar( const QString& ) ),
106              SLOT( changeStatusbar( const QString& ) ) );
107
108     connect( signalCollection, SIGNAL( openBoardRequested( const QString&, bool ) ),
109              SLOT( switchSubjectView( const QString&, bool ) ) );
110
111     connect( signalCollection, SIGNAL( openBoardRequested( const QString&, bool ) ),
112              m_subjectTab, SLOT( loadBoard( const QString&, bool ) ) );
113
114     connect( m_subjectTab, SIGNAL( showThreadRequested( const QString&, bool ) ),
115              SLOT( switchThreadView( const QString&, bool ) ) );
116
117     connect( m_subjectTab, SIGNAL( showThreadRequested( const QString&, bool ) ),
118              m_threadTab, SLOT( showThread( const QString&, bool ) ) );
119
120     connect( signalCollection, SIGNAL( signalThread( const Kita::Thread* ) ),
121              m_subjectTab, SLOT( updateThread( const Kita::Thread* ) ) );
122
123     connect( signalCollection, SIGNAL( signalThread( const Kita::Thread* ) ),
124              SLOT( slotThread( const Kita::Thread* ) ) );
125
126     connect( signalCollection, SIGNAL( writeSucceeded() ),
127              SLOT( slotWriteSucceeded() ) );
128
129     connect( signalCollection, SIGNAL( showThreadCompleted( const KURL& ) ),
130              SLOT( setUrl( const KURL& ) ) );
131
132     connect( m_threadTab, SIGNAL( sigHideSubject() ),
133              SLOT( hideSubject() ) );
134
135     connect( m_threadTab->manager(), SIGNAL( activePartChanged( KParts::Part* ) ),
136              SLOT( createGUI( KParts::Part* ) ) );
137
138     connect( m_boardView, SIGNAL( sigShowSubject() ),
139              SLOT( showSubject() ) );
140
141     connect( m_subjectTab, SIGNAL( loadBoardCompleted( const KURL& ) ),
142              SLOT( setUrl( const KURL& ) ) );
143
144     connect( signalCollection, SIGNAL( bookmarked( const QString&, bool ) ),
145              SLOT( bookmark( const QString&, bool ) ) );
146              
147     connect( m_urlLine, SIGNAL( returnPressed() ),
148              SLOT( slotURLLine() ) );
149
150     //QPopupMenu* popup = static_cast<QPopupMenu *>( factory() ->container( "window", this ) );
151     //connect( popup, SIGNAL( aboutToShow() ),
152     //         SLOT( windowMenuAboutToShow() ) );
153
154     QPopupMenu* settingsPopup = static_cast<QPopupMenu *>( factory() ->container( "settings", this ) );
155     connect( settingsPopup, SIGNAL( aboutToShow() ),
156              SLOT( settingsMenuAboutToShow() ) );
157
158     m_boardView->loadBoardList();
159     m_boardView->setFocus();
160     m_boardListAction->activate();
161     m_subjectListAction->activate(); // dummy code
162 }
163
164 KitaMainWindow::~KitaMainWindow()
165 {
166     if ( ! m_subjectListAction->isChecked() )
167         makeDockVisible( m_subjectDock );
168
169     saveAboneIDList();
170     saveAboneNameList();
171     saveAboneWordList();
172     
173     saveAsciiArt();
174
175     saveCompletion();
176
177     saveFavoriteBoards();
178
179     saveFavorites();
180
181     saveCache();
182
183     saveMainWindowSettings( KGlobal::config(), "MainWindow" );
184
185     writeConfig( KGlobal::config() );
186
187     writeDockConfig( KGlobal::config() );
188 }
189
190 void KitaMainWindow::load( const KURL& url )
191 {
192     QString target;
193     // the below code is what you should normally do.  in this
194     // example case, we want the url to our own.  you probably
195     // want to use this code instead for your app
196
197 #if 0
198     // download the contents
199     if ( KIO::NetAccess::download( url, target ) ) {
200         // set our caption
201         setCaption( url );
202
203         // load in the file (target is always local)
204         loadFile( target );
205
206         // and remove the temp file
207         KIO::NetAccess::removeTempFile( target );
208     }
209 #endif
210
211     setCaption( url.url() );
212     //    m_view->openURL(url);
213 }
214
215 void KitaMainWindow::setupActions()
216 {
217     KStdAction::openNew( this, SLOT( fileNew() ), actionCollection() );
218     KStdAction::quit( this, SLOT( close() ), actionCollection() );
219     KStdAction::copy( this, SLOT( slotEditCopy() ), actionCollection() );
220
221     m_toolbarAction = KStdAction::showToolbar( this,
222                       SLOT( optionsShowToolbar() ),
223                       actionCollection() );
224
225     m_statusbarAction = KStdAction::showStatusbar( this,
226                         SLOT( optionsShowStatusbar() ),
227                         actionCollection() );
228
229     m_boardListAction = new KToggleAction( i18n( "Show board list" ),
230                                            0,
231                                            this,
232                                            SLOT( windowShowBoardlist() ),
233                                            actionCollection(),
234                                            "window_show_board_list" );
235
236     m_subjectListAction = new KToggleAction( i18n( "Show subject list" ),
237                           0,
238                           this,
239                           SLOT( windowShowSubjectlist() ),
240                           actionCollection(),
241                           "window_show_subject_list" );
242
243     m_urlLine = new KLineEdit( "", 0 );
244     new KWidgetAction( m_urlLine,
245                        i18n( "URL Line" ),
246                        0,
247                        this,
248                        SLOT( slotURLLine() )         /* dummy */,
249                        actionCollection(), "url_line_action" );
250
251     KStdAction::keyBindings( this, SLOT( optionsConfigureKeys() ), actionCollection() );
252     KStdAction::configureToolbars( this, SLOT( optionsConfigureToolbars() ), actionCollection() );
253     KStdAction::preferences( this, SLOT( optionsPreferences() ), actionCollection() );
254
255     new KAction( i18n( "Load BoardList" ),
256                  0,
257                  m_boardView,
258                  SLOT( loadBoardList() ),
259                  actionCollection(),
260                  "load_board_list" );
261
262     new KAction( i18n( "reset windows" ),
263                  0,
264                  this,
265                  SLOT( resetWindows() ),
266                  actionCollection(),
267                  "reset_win" );
268
269     m_toggleViewAction = new KAction(
270         i18n( "&Toggle subject view and thread view" ),
271         KShortcut(Qt::Key_F7),
272         this,
273         SLOT( windowToggleView() ),
274         actionCollection(),
275         "window_toggle_view" );
276
277     // action for subjecttabwidget
278     new KAction( i18n( "Close Current Thread Tab" ),
279                  KStdAccel::close(),
280                  m_threadTab,
281                  SLOT( closeCurrentTab() ),
282                  actionCollection(),
283                  "threadtab_closetab" );
284     new KAction( i18n( "&Reload subject list"),
285                  KShortcut(Qt::CTRL | Qt::Key_F5),
286                  m_subjectTab,
287                  SLOT( reloadSubjectList() ),
288                  actionCollection(),
289                  "threadlist_reload" );
290
291     m_threadTab->manager()->addManagedTopLevelWidget( m_mainDock );
292     setXMLFile( "kitaui.rc" );
293     createGUI( m_threadTab->manager()->activePart() );
294 }
295
296 void KitaMainWindow::slotURLLine()
297 {
298     QString text = m_urlLine->text();
299     QString datURL = Kita::threadToDat( text );
300     m_threadTab->showThread( datURL, KitaConfig::alwaysUseTab() );
301 }
302
303 void KitaMainWindow::writeConfig( KConfig* config )
304 {
305     config->setGroup( "Global" );
306     config->writeEntry( "Font", KitaConfig::font() );
307     config->writeEntry( "ThreadFont", KitaConfig::threadFont() );
308     config->writeEntry( "ShowMailAddress", KitaConfig::showMailAddress() );
309     config->writeEntry( "MarkTime", KitaConfig::MarkTime() );
310     config->writeEntry( "ViewMode", KitaConfig::viewMode() );
311     config->writeEntry( "SortOrder", KitaConfig::sortOrder() );
312     config->writeEntry( "AlwaysUseTab", KitaConfig::alwaysUseTab() );
313     config->writeEntry( "ShowAA", KitaConfig::showAA() );
314     config->writeEntry( "AfterShowNum", KitaConfig::afterShowNum() );
315
316     config->setGroup( "Color" );
317     config->writeEntry( "Popup", KitaConfig::popupColor() );
318     config->writeEntry( "PopupBackground", KitaConfig::popupBackgroundColor() );
319 }
320
321 void KitaMainWindow::saveProperties( KConfig* config )
322 {
323     // the 'config' object points to the session managed
324     // config file.  anything you write here will be available
325     // later when this app is restored
326
327     //    if (m_view->currentURL() != QString::null)
328     //        config->writeEntry("lastURL", m_view->currentURL());
329     writeConfig( config );
330 }
331
332 void KitaMainWindow::readConfig( KConfig* config )
333 {
334     config->setGroup( "Global" );
335     KitaConfig::setFont( config->readFontEntry( "Font" ) );
336     KitaConfig::setThreadFont( config->readFontEntry( "ThreadFont" ) );
337     KitaConfig::setShowMailAddresss( config->readBoolEntry( "ShowMailAddress" ) );
338     KitaConfig::setMarkTime( config->readUnsignedNumEntry( "MarkTime" , 24 ) );
339     KitaConfig::setViewMode( config->readNumEntry( "ViewMode", KitaConfig::View_2pane ) );
340     KitaConfig::setSortOrder( config->readNumEntry( "SortOrder", KitaConfig::Order_Mark ) );
341     KitaConfig::setAlwaysUseTab( config->readBoolEntry( "AlwaysUseTab", false ) );
342     KitaConfig::setShowAA( config->readBoolEntry( "ShowAA", false ) );
343     KitaConfig::setAfterShowNum( config->readNumEntry( "AfterShowNum", 100 ) );
344
345     setFont( KitaConfig::font() );
346
347     config->setGroup( "Color" );
348
349     QColor popupColor = config->readColorEntry( "Popup" );
350     if ( popupColor.isValid() ) {
351         KitaConfig::setPopupColor( popupColor );
352     }
353
354     QColor popupBackgroundColor = config->readColorEntry( "PopupBackground" );
355     if ( popupColor.isValid() ) {
356         KitaConfig::setPopupBackgroundColor( popupBackgroundColor );
357     }
358 }
359
360 void KitaMainWindow::readProperties( KConfig* config )
361 {
362     // the 'config' object points to the session managed
363     // config file.  this function is automatically called whenever
364     // the app is being restored.  read in here whatever you wrote
365     // in 'saveProperties'
366
367     //    QString url = config->readEntry("lastURL");
368
369     //    if (url != QString::null)
370     //        m_view->openURL(KURL(url));
371     readConfig( config );
372 }
373
374 void KitaMainWindow::dragEnterEvent( QDragEnterEvent* event )
375 {
376     // accept uri drops only
377     event->accept( QUriDrag::canDecode( event ) );
378 }
379
380 void KitaMainWindow::dropEvent( QDropEvent* event )
381 {
382     // this is a very simplistic implementation of a drop event.  we
383     // will only accept a dropped URL.  the Qt dnd code can do *much*
384     // much more, so please read the docs there
385     QStrList uri;
386
387     // see if we can decode a URI.. if not, just ignore it
388     if ( QUriDrag::decode( event, uri ) ) {
389         // okay, we have a URI.. process it
390         QString url, target;
391         url = uri.first();
392
393         // load in the file
394         load( KURL( url ) );
395     }
396 }
397
398 void KitaMainWindow::fileNew()
399 {
400     // this slot is called whenever the File->New menu is selected,
401     // the New shortcut is pressed (usually CTRL+N) or the New toolbar
402     // button is clicked
403
404     // create a new window
405     ( new KitaMainWindow ) ->show();
406 }
407
408 void KitaMainWindow::optionsShowToolbar()
409 {
410     // this is all very cut and paste code for showing/hiding the
411     // toolbar
412     if ( m_toolbarAction->isChecked() ) {
413         toolBar() ->show();
414     } else {
415         toolBar() ->hide();
416     }
417 }
418
419 void KitaMainWindow::optionsShowStatusbar()
420 {
421     // this is all very cut and paste code for showing/hiding the
422     // statusbar
423     if ( m_statusbarAction->isChecked() ) {
424         statusBar() ->show();
425     } else {
426         statusBar() ->hide();
427     }
428 }
429
430 void KitaMainWindow::optionsConfigureKeys()
431 {
432     KKeyDialog dlg( TRUE, this);
433     QPtrList<KXMLGUIClient> actList = guiFactory()->clients();
434     for ( QPtrListIterator<KXMLGUIClient> act( actList ) ; act.current() ; ++act )
435     {
436         const KAboutData *dat = (*act)->instance()->aboutData();
437         dlg.insert( (*act)->actionCollection(),dat->programName() );
438     }
439     dlg.configure();
440 }
441
442 void KitaMainWindow::optionsConfigureToolbars()
443 {
444     // use the standard toolbar editor
445     KEditToolbar dlg( factory() );
446     connect( &dlg, SIGNAL( newToolbarConfig() ),
447              SLOT( newToolbarConfig() ) );
448     dlg.exec();
449 }
450
451 void KitaMainWindow::newToolbarConfig()
452 {
453     // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
454     // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
455     applyMainWindowSettings( KGlobal::config(), "MainWindow" );
456 }
457
458 void KitaMainWindow::windowShowBoardlist()
459 {
460     if ( m_boardListAction->isChecked() ) {
461         makeDockVisible( m_boardDock );
462     } else {
463         makeDockInvisible( m_boardDock );
464     }
465 }
466
467 void KitaMainWindow::windowShowSubjectlist()
468 {
469     if ( m_subjectListAction->isChecked() ) {
470         makeDockVisible( m_subjectDock );
471     } else {
472         makeDockInvisible( m_subjectDock );
473     }
474 }
475
476 void KitaMainWindow::resetWindows()
477 {
478     m_boardDock->manualDock( m_mainDock, KDockWidget::DockLeft, 20 );
479     m_subjectDock->manualDock( m_mainDock, KDockWidget::DockTop, 30 );
480 }
481
482 void KitaMainWindow::hideSubject()
483 {
484     if ( KitaConfig::viewMode() != KitaConfig::View_2pane ) return ;
485     if ( !m_subjectDock->isDockBackPossible() )
486         if ( m_subjectDock->mayBeHide() )
487             m_subjectListAction->activate();
488 }
489
490 void KitaMainWindow::showSubject()
491 {
492     if ( KitaConfig::viewMode() != KitaConfig::View_2pane ) return ;
493     if ( m_subjectDock->mayBeShow() )
494         m_subjectListAction->activate();
495 }
496
497 void KitaMainWindow::windowToggleView()
498 {
499     //FIXME: m_subjectDock->dockSite() & KDockWidget::DockCenter != 0 °Ê³°¤Î¤È¤­¤Ï¤É¤¦¤¹¤ë¡©
500     kdDebug() << "Do toggle" << endl;
501     if ( !m_subjectListAction->isChecked() || (m_subjectDock->dockSite() & KDockWidget::DockCenter == 0) ) return;
502     KDockWidget *w = m_subjectDock->isVisible() ? m_mainDock : m_subjectDock;
503     kdDebug() << QString( "toggle target: %1" ).arg( w->name() ) << endl;
504     w->makeDockVisible();
505     w->getWidget()->setFocus();
506 }
507
508 void KitaMainWindow::windowMenuAboutToShow()
509 {
510     //m_boardListAction->setChecked( m_boardDock->isVisible() );
511     //m_subjectListAction->setChecked( m_subjectDock->isVisible() );
512     //m_toggleViewAction->setEnabled(m_subjectDock->dockSite() & KDockWidget::DockCenter);
513 }
514
515 void KitaMainWindow::windowCloseTab()
516 {
517     m_threadTab->closeCurrentTab();
518 }
519
520 void KitaMainWindow::settingsMenuAboutToShow()
521 {
522     m_toolbarAction->setChecked( toolBar() ->isVisible() );
523     m_statusbarAction->setChecked( statusBar() ->isVisible() );
524 }
525
526 void KitaMainWindow::optionsPreferences()
527 {
528     // popup some sort of preference dialog, here
529     KitaPreferences dlg;
530
531     connect( &dlg, SIGNAL( fontChanged( const QFont& ) ),
532              SLOT( setFont( const QFont& ) ) );
533     connect( &dlg, SIGNAL( threadFontChanged( const QFont& ) ),
534              SLOT( setThreadFont( const QFont& ) ) );
535
536     // XXX
537     dlg.setInitialSize( QSize( 600, 400 ) );
538     if ( dlg.exec() ) {
539         // redo your settings
540     }
541 }
542
543 void KitaMainWindow::changeStatusbar( const QString& text )
544 {
545     // display the text on the statusbar
546     statusBar() ->message( text );
547 }
548
549 void KitaMainWindow::changeCaption( const QString& text )
550 {
551     // display the text on the caption
552     setCaption( text );
553 }
554
555 void KitaMainWindow::setupView()
556 {
557     m_mainDock = createDockWidget( "main", 0L, 0L, i18n( "main" ), i18n( "main" ) );
558     m_threadTab = new KitaThreadTabWidget( m_mainDock );
559     m_mainDock->setWidget( m_threadTab );
560     m_mainDock->setDockSite( KDockWidget::DockFullSite );
561     m_mainDock->setEnableDocking( KDockWidget::DockNone );
562     connect( Kita::SignalCollection::getInstance(), SIGNAL( openURLRequest( const KURL&, const KParts::URLArgs& ) ),
563              SLOT( slotOpenURLRequest( const KURL&, const KParts::URLArgs& ) ) );
564
565     /* emit when this widget is deactivated */
566     connect( this, SIGNAL( windowDeactivated() ),
567              Kita::SignalCollection::getInstance(), SIGNAL( windowDeactivated() ));
568     
569     /* If this widget is active and receives
570        signal isKitaActive, then emit signal kitaIsActive. */
571     connect( Kita::SignalCollection::getInstance(), SIGNAL( isKitaActive() ),
572              this, SLOT( slotIsKitaActive() ) );
573
574     connect( this, SIGNAL( kitaIsActive() ),
575              Kita::SignalCollection::getInstance(), SIGNAL( kitaIsActive() ) );
576     
577     setView( m_mainDock );
578     setMainDockWidget( m_mainDock );
579
580     m_subjectDock = createDockWidget( "subject", 0L, 0L, i18n( "subject" ), i18n( "subject" ) );
581     m_subjectTab = new KitaSubjectTabWidget( m_subjectDock );
582     m_subjectDock->setWidget( m_subjectTab );
583     m_subjectDock->setDockSite( KDockWidget::DockNone );
584     connect( m_subjectDock, SIGNAL( headerCloseButtonClicked() ), SLOT( closeSubjectView() ) );
585     connect( m_subjectDock, SIGNAL( iMBeingClosed() ), SLOT( closeSubjectView() ) );
586
587     m_boardDock = createDockWidget( "board", 0L, 0L, i18n( "board" ), i18n( "board" ) );
588     m_boardView = new KitaBoardView( m_boardDock );
589     m_boardDock->setWidget( m_boardView );
590     m_boardDock->setDockSite( KDockWidget::DockNone );
591     connect( m_boardDock, SIGNAL( headerCloseButtonClicked() ), SLOT( closeBoardView() ) );
592     connect( m_boardDock, SIGNAL( iMBeingClosed() ), SLOT( closeBoardView() ) );
593
594     m_boardDock->manualDock( m_mainDock, KDockWidget::DockLeft, 20 );
595     m_subjectDock->manualDock( m_mainDock, KDockWidget::DockTop, 30 );
596
597     /* setup kitanavi */
598     KitaNavi::createKitaNavi(this,m_threadTab);
599 }
600
601 void KitaMainWindow::closeSubjectView()
602 {
603     m_subjectListAction->setChecked( FALSE );
604 }
605
606 void KitaMainWindow::closeBoardView()
607 {
608    m_boardListAction->setChecked( FALSE );
609 }
610
611 void KitaMainWindow::slotOpenURLRequest( const KURL& url, const KParts::URLArgs& args )
612
613     kdDebug() << QString( "Requested OpenURL: \"%1\"" ).arg( url.url() ) << endl;
614     kdDebug() << QString( "content type: \"%1\"" ).arg( args.contentType() ) << endl;
615     kdDebug() << QString( "service type: \"%1\"" ).arg( args.serviceType ) << endl;
616     kdDebug() << QString( "NewTab: %1, reload: %2" )
617                         .arg( args.newTab() ? "yes" : "no" )
618                         .arg( args.reload ? "yes" : "no" ) << endl;
619     QString mimetype = KIO::NetAccess::mimetype( url );
620     kdDebug() << QString( "queried MIME type: \"%1\"" ).arg( mimetype ) << endl;
621     if ( mimetype.startsWith( "image/" ) ) {
622         KService::Ptr service = KServiceTypeProfile::preferredService( mimetype, "KParts/ReadOnlyPart" );
623         if ( service ) {
624             QString libName = QFile::encodeName( service->library() );
625             m_threadTab->showAlternativeView( url, libName, mimetype );
626             return;
627         }
628     }
629     KURL datURL = Kita::ParseMisc::parseURLonly( url );
630
631     QRegExp regexp( "http://([^/]*)/([^/]*)/dat/(.*)\\.dat" );
632     if ( regexp.search( datURL.url() ) == -1 ) {
633         new KRun( url );
634     } else {
635         m_threadTab->showThread( url.prettyURL(), true );
636     }
637 }
638
639 void KitaMainWindow::loadCache()
640 {
641     KitaThreadInfo * cache = KitaThreadInfo::getInstance();
642     QString cacheConfigPath = locateLocal( "appdata", "cache" );
643     QFile file( cacheConfigPath );
644     if ( file.open( IO_ReadOnly ) ) {
645         QDataStream stream( &file );
646         stream >> *cache;
647     }
648 }
649
650 void KitaMainWindow::saveCache()
651 {
652     KitaThreadInfo * cache = KitaThreadInfo::getInstance();
653     QString cacheConfigPath = locateLocal( "appdata", "cache" );
654     QFile file( cacheConfigPath );
655     if ( file.open( IO_WriteOnly ) ) {
656         QDataStream stream( &file );
657         stream << *cache;
658     }
659 }
660
661 /*!
662     \fn KitaMainWindow::setFont(QFont& font)
663  */
664
665 void KitaMainWindow::setFont( const QFont& font )
666 {
667     m_subjectTab->setFont( font );
668     m_boardView->setFont( font );
669 }
670
671 void KitaMainWindow::setThreadFont( const QFont& font )
672 {
673     m_threadTab->setFont( font );
674 }
675
676 void KitaMainWindow::slotWriteSucceeded()
677 {
678     statusBar() ->message( i18n( "posting succeeded." ) );
679 }
680
681 void KitaMainWindow::setUrl( const KURL& url )
682 {
683     m_urlLine->setText( url.url() );
684 }
685
686 void KitaMainWindow::bookmark( const QString& datURL, bool on )
687 {
688     FavoriteThreads * favorite = FavoriteThreads::getInstance();
689
690     if ( on ) {
691         favorite->insert( datURL );
692     } else {
693         favorite->remove( datURL );
694     }
695 }
696
697 void KitaMainWindow::loadFavorites()
698 {
699     QString favoritesConfigPath = locateLocal( "appdata", "favorites.xml" );
700     QFile file( favoritesConfigPath );
701     if ( file.open( IO_ReadOnly ) ) {
702         QTextStream stream( &file );
703         stream.setEncoding( QTextStream::UnicodeUTF8 );
704
705         QString xml = stream.read();
706         FavoriteThreads::readFromXML( xml );
707     }
708 }
709
710 void KitaMainWindow::saveFavorites()
711 {
712     QString favoritesConfigPath = locateLocal( "appdata", "favorites.xml" );
713     QFile file( favoritesConfigPath );
714     if ( file.open( IO_WriteOnly ) ) {
715         QTextStream stream( &file );
716         stream.setEncoding( QTextStream::UnicodeUTF8 );
717         stream << FavoriteThreads::getInstance() ->toXML();
718     }
719 }
720
721 void KitaMainWindow::loadCompletion()
722 {
723     QString configPath = locateLocal( "appdata", "completion" );
724     KSimpleConfig config( configPath );
725
726     KitaConfig::setNameCompletionItems( config.readListEntry( "name" ) );
727 }
728
729 void KitaMainWindow::saveCompletion()
730 {
731     QString configPath = locateLocal( "appdata", "completion" );
732     KSimpleConfig config( configPath );
733
734     config.writeEntry( "name", KitaConfig::nameCompletion() ->items() );
735     config.sync();
736 }
737
738 void KitaMainWindow::loadAsciiArt()
739 {
740     QString configPath = locateLocal( "appdata", "asciiart" );
741     QFile file( configPath );
742     if ( file.open( IO_ReadOnly ) ) {
743         QTextStream stream( &file );
744         stream.setEncoding( QTextStream::UnicodeUTF8 );
745
746         QStringList list;
747         QString str;
748
749         while ( ( str = stream.readLine() ) != QString::null ) {
750             if ( ! str.isEmpty() ) {
751                 list << str;
752             }
753         }
754         KitaConfig::setAsciiArtList( list );
755     }
756 }
757
758 void KitaMainWindow::saveAsciiArt()
759 {
760     QString configPath = locateLocal( "appdata", "asciiart" );
761     QFile file( configPath );
762     if ( file.open( IO_WriteOnly ) ) {
763         QTextStream stream( &file ) ;
764         stream.setEncoding( QTextStream::UnicodeUTF8 );
765
766         QStringList list = KitaConfig::asciiArtList();
767         QStringList::iterator it;
768         for ( it = list.begin(); it != list.end(); ++it ) {
769             stream << ( *it ) << endl;
770         }
771     }
772 }
773
774 void KitaMainWindow::loadFavoriteBoards()
775 {
776     QString configPath = locateLocal( "appdata", "favorite_boards.xml" );
777     QFile file( configPath );
778     if ( file.open( IO_ReadOnly ) ) {
779         QTextStream stream( &file );
780         stream.setEncoding( QTextStream::UnicodeUTF8 );
781
782         QString xml = stream.read();
783         Kita::FavoriteBoards::readFromXML( xml );
784     }
785 }
786
787 void KitaMainWindow::saveFavoriteBoards()
788 {
789     QString configPath = locateLocal( "appdata", "favorite_boards.xml" );
790     QFile file( configPath );
791     if ( file.open( IO_WriteOnly ) ) {
792         QTextStream stream( &file );
793         stream.setEncoding( QTextStream::UnicodeUTF8 );
794         stream << Kita::FavoriteBoards::toXML();
795     }
796 }
797
798 void KitaMainWindow::loadAboneIDList()
799 {
800     QString configPath = locateLocal( "appdata", "abone_id" );
801     QFile file( configPath );
802     if ( file.open( IO_ReadOnly ) ) {
803         QTextStream stream( &file );
804         stream.setEncoding( QTextStream::UnicodeUTF8 );
805         
806         QStringList list;
807         QString str;
808     
809         while ( ( str = stream.readLine() ) != QString::null ) {
810             if ( ! str.isEmpty() ) {
811                 list << str;
812             }
813         }
814         KitaConfig::setAboneIDList( list );
815     }
816 }
817
818 void KitaMainWindow::saveAboneIDList()
819 {
820     QString configPath = locateLocal( "appdata", "abone_id" );
821     QFile file( configPath );
822     if ( file.open( IO_WriteOnly ) ) {
823         QTextStream stream( &file ) ;
824         stream.setEncoding( QTextStream::UnicodeUTF8 );
825
826         QStringList list = KitaConfig::aboneIDList();
827         QStringList::iterator it;
828         for ( it = list.begin(); it != list.end(); ++it ) {
829             stream << ( *it ) << endl;
830         }
831     }    
832 }
833
834 void KitaMainWindow::loadAboneNameList()
835 {
836     QString configPath = locateLocal( "appdata", "abone_name" );
837     QFile file( configPath );
838     if ( file.open( IO_ReadOnly ) ) {
839         QTextStream stream( &file );
840         stream.setEncoding( QTextStream::UnicodeUTF8 );
841         
842         QStringList list;
843         QString str;
844     
845         while ( ( str = stream.readLine() ) != QString::null ) {
846             if ( ! str.isEmpty() ) {
847                 list << str;
848             }
849         }
850         KitaConfig::setAboneNameList( list );
851     }
852 }
853
854 void KitaMainWindow::saveAboneNameList()
855 {
856     QString configPath = locateLocal( "appdata", "abone_name" );
857     QFile file( configPath );
858     if ( file.open( IO_WriteOnly ) ) {
859         QTextStream stream( &file ) ;
860         stream.setEncoding( QTextStream::UnicodeUTF8 );
861
862         QStringList list = KitaConfig::aboneNameList();
863         QStringList::iterator it;
864         for ( it = list.begin(); it != list.end(); ++it ) {
865             stream << ( *it ) << endl;
866         }
867     }    
868 }
869
870 void KitaMainWindow::loadAboneWordList()
871 {
872     QString configPath = locateLocal( "appdata", "abone_word" );
873     QFile file( configPath );
874     if ( file.open( IO_ReadOnly ) ) {
875         QTextStream stream( &file );
876         stream.setEncoding( QTextStream::UnicodeUTF8 );
877         
878         QStringList list;
879         QString str;
880     
881         while ( ( str = stream.readLine() ) != QString::null ) {
882             if ( ! str.isEmpty() ) {
883                 list << str;
884             }
885         }
886         KitaConfig::setAboneWordList( list );
887     }
888 }
889
890 void KitaMainWindow::saveAboneWordList()
891 {
892     QString configPath = locateLocal( "appdata", "abone_word" );
893     QFile file( configPath );
894     if ( file.open( IO_WriteOnly ) ) {
895         QTextStream stream( &file ) ;
896         stream.setEncoding( QTextStream::UnicodeUTF8 );
897
898         QStringList list = KitaConfig::aboneWordList();
899         QStringList::iterator it;
900         for ( it = list.begin(); it != list.end(); ++it ) {
901             stream << ( *it ) << endl;
902         }
903     }    
904 }
905
906 void KitaMainWindow::switchSubjectView( const QString&, bool )
907 {
908     if ( m_subjectListAction->isChecked() )
909         m_subjectDock->makeDockVisible();
910 }
911
912 void KitaMainWindow::switchThreadView( const QString&, bool )
913 {
914     m_mainDock->makeDockVisible();
915 }
916
917 void KitaMainWindow::slotThread( const Kita::Thread* thread )
918 {
919     setCaption( thread->name() + QString( " (%1)" ).arg( thread->resNum() ) );
920 }
921
922 void KitaMainWindow::slotEditCopy()
923 {
924     QWidget * widget = kapp->focusWidget();
925
926     if ( widget ) {
927         QKeyEvent e( QEvent::KeyPress, Key_C, 'C', ControlButton );
928         QApplication::sendEvent( widget, &e );
929     }
930 }
931
932 /* when window is deactivated, emit signal to popup */ /* protected */
933 void KitaMainWindow::windowActivationChange ( bool  )
934 {
935    if(!isActiveWindow()) emit windowDeactivated();
936 }
937
938 /* private slot */
939 void KitaMainWindow::slotIsKitaActive(){
940     if(isActiveWindow()) emit kitaIsActive();
941 }
942
943
944 #include "kita.moc"