OSDN Git Service

refactoring.
[kita/kita.git] / kita / src / mainwindow.cpp
1 /***************************************************************************
2 *   Copyright (C) 2004 by Kita Developers                                 *
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 "mainwindow.h"
12
13 #include "prefs/prefs.h"
14
15 #include "thread/threadview.h"
16 #include "thread/threadtabwidget.h"
17
18 #include "board/boardview.h"
19 #include "board/boardtabwidget.h"
20 #include "bbs/bbsview.h"
21 #include "bbs/bbstabwidget.h"
22 #include "favoriteswindow.h"
23
24 #include "write/writetabwidget.h"
25
26 #include "libkita/threadinfo.h"
27 #include "libkita/favoriteboards.h"
28 #include "libkita/favoritethreads.h"
29 #include "libkita/kita_misc.h"
30 #include "libkita/kitaconfig.h"
31 #include "libkita/signalcollection.h"
32 #include "libkita/account.h"
33 #include "libkita/imgmanager.h"
34 #include "libkita/datmanager.h"
35 #include "libkita/boardmanager.h"
36
37 #include "image/imagetabwidget.h"
38
39 #include <qdragobject.h>
40 #include <qtextcodec.h>
41 #include <qevent.h>
42 #include <qregexp.h>
43 #include <qmessagebox.h>
44 #include <qclipboard.h>
45
46 #include <klineedit.h>
47 #include <kglobal.h>
48 #include <klocale.h>
49 #include <kiconloader.h>
50 #include <kmenubar.h>
51 #include <kstatusbar.h>
52 #include <kkeydialog.h>
53 #include <kaccel.h>
54 #include <kio/netaccess.h>
55 #include <kuserprofile.h>
56 #include <kfiledialog.h>
57 #include <kconfig.h>
58 #include <kurl.h>
59 #include <krun.h>
60 #include <kstandarddirs.h>
61 #include <kdebug.h>
62 #include <ksimpleconfig.h>
63 #include <kedittoolbar.h>
64 #include <kstdaccel.h>
65 #include <kaction.h>
66 #include <kstdaction.h>
67 #include <kshortcut.h>
68 #include <kaboutdata.h>
69 #include <kparts/partmanager.h>
70 #include <kdeversion.h>
71 #include <kglobal.h>
72
73 KitaMainWindow::KitaMainWindow()
74         : KParts::DockMainWindow( 0, "Kita" ),
75         m_printer( 0 )
76 {
77     // FIXME: merge *.po
78     KGlobal::locale() ->insertCatalogue( "kitapart" );
79
80     // accept dnd
81     setAcceptDrops( true );
82
83     // setup imgmanager
84     Kita::ImgManager::setup( this );
85
86     // setup view, dock
87     setupView();
88
89     // then, setup our actions
90     setupActions();
91
92     // load cache
93     loadCache();
94
95     // load completion
96     loadCompletion();
97
98     // load style sheet
99     loadStyleSheet();
100
101     // load ascii art
102     loadAsciiArt();
103
104     // load abone lists
105     loadAboneIDList();
106     loadAboneNameList();
107     loadAboneWordList();
108
109     // and a status bar
110     statusBar() ->show();
111
112     // read dock status
113     m_bbsDock->loadSession();
114     m_boardDock->loadSession();
115     m_threadDock->loadSession();
116     m_naviDock->loadSession();
117     m_imageDock->loadSession();
118     m_writeDock->loadSession();
119     QString dockConfigPath = locateLocal( "appdata", "dock.conf" );
120     KConfig dockConfig( dockConfigPath );
121     readDockConfig( &dockConfig );
122
123     // show subject dock
124     m_boardDock->slotShowDock();
125
126     // show thread view
127     m_threadDock->slotShowDock();
128
129     // hide writedock
130     makeDockInvisible( m_writeDock );
131     m_showImgViewAction->setChecked( FALSE );
132
133     // hide kitanavi
134     makeDockInvisible( m_naviDock );
135     m_showNaviAction->setChecked( FALSE );
136
137     // hide imageviewer
138     makeDockInvisible( m_imageDock );
139     m_showImgViewAction->setChecked( FALSE );
140
141
142     KitaConfig::readConfig( KGlobal::config() );
143
144     // apply the saved mainwindow settings, if any, and ask the mainwindow
145     // to automatically save settings if changed: window size, toolbar
146     // position, icon size, etc.
147     setAutoSaveSettings();
148
149     // font
150     setFont( KitaConfig::listFont() );
151
152     // allow the view to change the statusbar and caption
153     Kita::SignalCollection* signalCollection = Kita::SignalCollection::getInstance();
154
155     connect( signalCollection, SIGNAL( openURLRequest( const KURL&, const KParts::URLArgs& ) ),
156              SLOT( slotOpenURLRequest( const KURL&, const KParts::URLArgs& ) ) );
157
158     connect( signalCollection, SIGNAL( openURLRequestExt(
159                                            const KURL&, const KParts::URLArgs&, QString, int,
160                                            const KURL& ) ),
161              SLOT( slotOpenURLRequestExt(
162                        const KURL& , const KParts::URLArgs&, QString, int,
163                        const KURL& ) ) );
164
165     connect( signalCollection, SIGNAL( setMainCaption( const QString& ) ),
166              SLOT( slotSetMainCaption( const QString& ) ) );
167
168     connect( signalCollection, SIGNAL( setMainStatusbar( const QString& ) ),
169              SLOT( slotSetMainStatusbar( const QString& ) ) );
170
171     connect( signalCollection, SIGNAL( setMainURLLine( const KURL& ) ),
172              SLOT( setUrl( const KURL& ) ) );
173
174     connect( signalCollection, SIGNAL( bookmarked( const QString&, bool ) ),
175              SLOT( bookmark( const QString&, bool ) ) );
176
177     connect( this, SIGNAL( favoritesUpdated() ),
178              signalCollection, SIGNAL( favoritesUpdated() ) );
179
180     connect( m_urlLine, SIGNAL( returnPressed() ),
181              SLOT( slotURLLine() ) );
182
183     QPopupMenu* settingsPopup = static_cast<QPopupMenu *>( factory() ->container( "settings", this ) );
184     connect( settingsPopup, SIGNAL( aboutToShow() ),
185              SLOT( settingsMenuAboutToShow() ) );
186
187     // load favorite boards;
188     loadFavoriteBoards();
189
190     // load boad list
191     {
192         QString configPath = locateLocal( "appdata", "board_list" );
193         if ( QFile::exists( configPath ) ) {
194             m_bbsTab->showBoardList();
195             m_bbsTab->loadOpened();
196         } else {
197             m_bbsTab->updateBoardList();
198         }
199     }
200
201     // load favorites
202     loadFavorites();
203
204     // show board dock
205     m_bbsDock->slotShowDock();
206
207     // update favorite list
208     emit favoritesUpdated();
209
210     if ( KitaConfig::autoLogin() ) {
211         login();
212     }
213 }
214
215 KitaMainWindow::~KitaMainWindow()
216 {
217     /* save dock status */
218     m_bbsDock->saveSession();
219     m_boardDock->saveSession();
220     m_threadDock->saveSession();
221     m_naviDock->saveSession();
222     m_imageDock->saveSession();
223     m_writeDock->saveSession();
224
225     saveAboneIDList();
226     saveAboneNameList();
227     saveAboneWordList();
228
229     saveStyleSheet();
230
231     saveAsciiArt();
232
233     saveCompletion();
234
235     saveFavoriteBoards();
236
237     saveFavorites();
238
239     saveCache();
240
241     saveMainWindowSettings( KGlobal::config(), "MainWindow" );
242
243     KitaConfig::writeConfig( KGlobal::config() );
244
245     QString dockConfigPath = locateLocal( "appdata", "dock.conf" );
246     KConfig dockConfig( dockConfigPath );
247     writeDockConfig( &dockConfig );
248
249     delete m_bbsDock;
250     delete m_threadDock;
251     delete m_naviDock;
252     delete m_imageDock;
253     delete m_writeDock;
254
255     Kita::DatManager::deleteAllDatInfo();
256 }
257
258 void KitaMainWindow::load( const KURL& url )
259 {
260     QString target;
261     // the below code is what you should normally do.  in this
262     // example case, we want the url to our own.  you probably
263     // want to use this code instead for your app
264
265 #if 0
266     // download the contents
267     if ( KIO::NetAccess::download( url, target ) ) {
268         // set our caption
269         setCaption( url );
270
271         // load in the file (target is always local)
272         loadFile( target );
273
274         // and remove the temp file
275         KIO::NetAccess::removeTempFile( target );
276     }
277 #endif
278
279     setCaption( url.url() );
280     //    m_view->openURL(url);
281 }
282
283 void KitaMainWindow::setupActions()
284 {
285     KStdAction::quit( this, SLOT( close() ), actionCollection() );
286     KStdAction::copy( this, SLOT( slotEditCopy() ), actionCollection() );
287
288     m_toolbarAction = KStdAction::showToolbar( this,
289                       SLOT( optionsShowToolbar() ),
290                       actionCollection() );
291
292     m_statusbarAction = KStdAction::showStatusbar( this,
293                         SLOT( optionsShowStatusbar() ),
294                         actionCollection() );
295
296     m_boardListAction = new KToggleAction( i18n( "Show board list" ),
297                                            0,
298                                            m_bbsDock,
299                                            SLOT( slotToggleShowHide() ),
300                                            actionCollection(),
301                                            "window_show_board_list" );
302
303     m_subjectListAction = new KToggleAction( i18n( "Show subject list" ),
304                           0,
305                           m_boardDock,
306                           SLOT( slotToggleShowHide() ),
307                           actionCollection(),
308                           "window_show_subject_list" );
309
310     m_showImgViewAction = new KToggleAction( i18n( "Show Image Viewer" ),
311                           0,
312                           m_imageDock,
313                           SLOT( slotToggleShowHide() ),
314                           actionCollection(),
315                           "window_show_imgviewer" );
316
317     m_showNaviAction = new KToggleAction( i18n( "Show KitaNavi" ),
318                                           0,
319                                           m_naviDock,
320                                           SLOT( slotToggleShowHide() ),
321                                           actionCollection(),
322                                           "window_show_kitanavi" );
323
324     m_showWriteDockAction = new KToggleAction( i18n( "Show Write Dock" ),
325                             0,
326                             m_writeDock,
327                             SLOT( slotToggleShowHide() ),
328                             actionCollection(),
329                             "window_show_writedock" );
330
331     m_urlLine = new KLineEdit( "", 0 );
332
333     new KWidgetAction( m_urlLine,
334                        i18n( "URL Line" ),
335                        0,
336                        this,
337                        SLOT( slotURLLine() ),
338                        actionCollection(), "url_line_action" );
339
340     KStdAction::keyBindings( this, SLOT( optionsConfigureKeys() ), actionCollection() );
341     KStdAction::configureToolbars( this, SLOT( optionsConfigureToolbars() ), actionCollection() );
342     KStdAction::preferences( this, SLOT( optionsPreferences() ), actionCollection() );
343
344     /*    new KAction( i18n( "Edit Favorites" ),
345                      0,
346                      this,
347                      SLOT( favoritesEdit() ),
348                      actionCollection(),
349                      "favorites_edit" );*/
350
351     new KAction( i18n( "Load board list" ),
352                  0,
353                  m_bbsTab,
354                  SLOT( updateBoardList() ),
355                  actionCollection(),
356                  "load_board_list" );
357
358     new KAction( i18n( "reset windows" ),
359                  0,
360                  this,
361                  SLOT( resetWindowsCust() ),
362                  actionCollection(),
363                  "reset_wincust" );
364
365     new KAction( i18n( "default 1" ),
366                  0,
367                  this,
368                  SLOT( resetWindowsDef1() ),
369                  actionCollection(),
370                  "reset_windef1" );
371
372     new KAction( i18n( "default 2" ),
373                  0,
374                  this,
375                  SLOT( resetWindowsDef2() ),
376                  actionCollection(),
377                  "reset_windef2" );
378
379     new KAction( i18n( "default 3" ),
380                  0,
381                  this,
382                  SLOT( resetWindowsDef3() ),
383                  actionCollection(),
384                  "reset_windef3" );
385
386     m_toggleViewAction = new KAction(
387                              i18n( "&Toggle subject view and thread view" ),
388                              KShortcut( Qt::Key_F7 ),
389                              this,
390                              SLOT( windowToggleView() ),
391                              actionCollection(),
392                              "window_toggle_view" );
393
394     new KAction( i18n( "Login" ),
395                  0,
396                  this,
397                  SLOT( login() ),
398                  actionCollection(),
399                  "login" );
400
401     setXMLFile( "kitaui.rc" );
402     KMainWindow::createGUI();
403     factory() ->addClient( m_bbsTab );
404     factory() ->addClient( m_boardTab );
405     factory() ->addClient( m_threadTab );
406     factory() ->addClient( m_imageTab );
407     factory() ->addClient( m_naviTab );
408     factory() ->addClient( m_writeTab );
409 }
410
411 void KitaMainWindow::slotURLLine()
412 {
413     KURL url = m_urlLine->text();
414     KURL datURL = Kita::getDatURL( url );
415     m_threadDock->slotShowThread( datURL, KitaConfig::alwaysUseTab() );
416 }
417
418 void KitaMainWindow::saveProperties( KConfig* )
419 {
420     // the 'config' object points to the session managed
421     // config file.  anything you write here will be available
422     // later when this app is restored
423
424     //    if (m_view->currentURL() != QString::null)
425     //        config->writeEntry("lastURL", m_view->currentURL());
426     //    KitaConfig::writeConfig( config );
427 }
428
429 void KitaMainWindow::readProperties( KConfig* )
430 {
431     // the 'config' object points to the session managed
432     // config file.  this function is automatically called whenever
433     // the app is being restored.  read in here whatever you wrote
434     // in 'saveProperties'
435
436     //    QString url = config->readEntry("lastURL");
437
438     //    if (url != QString::null)
439     //        m_view->openURL(KURL(url));
440     //    KitaConfig::readConfig( config );
441 }
442
443 void KitaMainWindow::dragEnterEvent( QDragEnterEvent* event )
444 {
445     // accept uri drops only
446     event->accept( QUriDrag::canDecode( event ) );
447 }
448
449 void KitaMainWindow::dropEvent( QDropEvent* event )
450 {
451     // this is a very simplistic implementation of a drop event.  we
452     // will only accept a dropped URL.  the Qt dnd code can do *much*
453     // much more, so please read the docs there
454     QStrList uri;
455
456     // see if we can decode a URI.. if not, just ignore it
457     if ( QUriDrag::decode( event, uri ) ) {
458         // okay, we have a URI.. process it
459         QString url, target;
460         url = uri.first();
461
462         // load in the file
463         load( KURL( url ) );
464     }
465 }
466
467 void KitaMainWindow::optionsShowToolbar()
468 {
469     // this is all very cut and paste code for showing/hiding the
470     // toolbar
471     if ( m_toolbarAction->isChecked() ) {
472         toolBar() ->show();
473     } else {
474         toolBar() ->hide();
475     }
476 }
477
478 void KitaMainWindow::optionsShowStatusbar()
479 {
480     // this is all very cut and paste code for showing/hiding the
481     // statusbar
482     if ( m_statusbarAction->isChecked() ) {
483         statusBar() ->show();
484     } else {
485         statusBar() ->hide();
486     }
487 }
488
489 void KitaMainWindow::optionsConfigureKeys()
490 {
491     KKeyDialog dlg( TRUE, this );
492     dlg.insert( actionCollection(), "Kita" );
493     dlg.configure();
494 }
495
496 void KitaMainWindow::optionsConfigureToolbars()
497 {
498     // use the standard toolbar editor
499     KEditToolbar dlg( factory() );
500     connect( &dlg, SIGNAL( newToolbarConfig() ),
501              SLOT( newToolbarConfig() ) );
502     dlg.exec();
503 }
504
505 void KitaMainWindow::newToolbarConfig()
506 {
507     // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
508     // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
509     applyMainWindowSettings( KGlobal::config(), "MainWindow" );
510 }
511
512 void KitaMainWindow::resetWindowsCust() { resetWindows( 0 ); }
513 void KitaMainWindow::resetWindowsDef1() { resetWindows( 1 ); }
514 void KitaMainWindow::resetWindowsDef2() { resetWindows( 2 ); }
515 void KitaMainWindow::resetWindowsDef3() { resetWindows( 3 ); }
516
517 void KitaMainWindow::resetWindows( int pattern )
518 {
519     if ( !m_dummyDock || !m_threadDock || !m_bbsDock
520             || !m_boardDock || !m_naviDock || !m_imageDock || !m_writeDock ) return ;
521
522     makeDockVisible( m_threadDock );
523     makeDockVisible( m_bbsDock );
524     makeDockVisible( m_boardDock );
525     makeDockVisible( m_naviDock );
526     makeDockVisible( m_imageDock );
527     makeDockVisible( m_writeDock );
528
529     makeDockInvisible( m_threadDock );
530     makeDockInvisible( m_bbsDock );
531     makeDockInvisible( m_boardDock );
532     makeDockInvisible( m_naviDock );
533     makeDockInvisible( m_imageDock );
534     makeDockInvisible( m_writeDock );
535
536     m_threadDock->manualDock( m_dummyDock, KDockWidget::DockTop, 100 );
537     m_bbsDock->manualDock( m_threadDock, KDockWidget::DockLeft, 20 );
538     m_boardDock->manualDock( m_threadDock, KDockWidget::DockTop, 25 );
539     m_imageDock->manualDock( m_threadDock, KDockWidget::DockTop, 25 );
540     m_writeDock->manualDock( m_threadDock, KDockWidget::DockBottom, 75 );
541     m_naviDock->manualDock( m_threadDock, KDockWidget::DockBottom, 50 );
542
543     switch ( pattern ) {
544
545         /*----------------------------------------*/
546     case 0:
547
548         /* setSession( docked, tabbed ) */
549         m_threadDock ->setSession( TRUE, FALSE );
550         m_bbsDock ->setSession( TRUE, FALSE );
551         m_boardDock->setSession( TRUE, FALSE );
552         m_imageDock ->setSession( TRUE, FALSE );
553         m_writeDock ->setSession( TRUE, FALSE );
554         m_naviDock ->setSession( TRUE, FALSE );
555
556         if ( m_boardListAction ) m_boardListAction->setChecked( TRUE );
557         if ( m_subjectListAction ) m_subjectListAction->setChecked( TRUE );
558         if ( m_showImgViewAction ) m_showImgViewAction->setChecked( TRUE );
559         if ( m_showNaviAction ) m_showNaviAction->setChecked( TRUE );
560         if ( m_showWriteDockAction ) m_showWriteDockAction->setChecked( TRUE );
561
562         break;
563
564         /*----------------------------------------*/
565     case 1:
566
567         m_imageDock->toDesktop();
568         m_writeDock->toDesktop();
569         m_naviDock->toDesktop();
570
571         makeDockInvisible( m_imageDock );
572         makeDockInvisible( m_writeDock );
573         makeDockInvisible( m_naviDock );
574
575         /* setSession( docked, tabbed ) */
576         m_threadDock ->setSession( TRUE, FALSE );
577         m_bbsDock ->setSession( TRUE, FALSE );
578         m_boardDock->setSession( TRUE, FALSE );
579         m_imageDock ->setSession( FALSE, FALSE );
580         m_writeDock ->setSession( FALSE, FALSE );
581         m_naviDock ->setSession( FALSE, FALSE );
582
583         if ( m_boardListAction ) m_boardListAction->setChecked( TRUE );
584         if ( m_subjectListAction ) m_subjectListAction->setChecked( TRUE );
585         if ( m_showImgViewAction ) m_showImgViewAction->setChecked( FALSE );
586         if ( m_showNaviAction ) m_showNaviAction->setChecked( FALSE );
587         if ( m_showWriteDockAction ) m_showWriteDockAction->setChecked( FALSE );
588
589         break;
590
591         /*----------------------------------------*/
592     case 2:
593
594         m_boardDock->manualDock( m_threadDock, KDockWidget::DockCenter, 0 );
595
596         m_imageDock->toDesktop();
597         m_writeDock->toDesktop();
598         m_naviDock->toDesktop();
599
600         makeDockInvisible( m_imageDock );
601         makeDockInvisible( m_writeDock );
602         makeDockInvisible( m_naviDock );
603
604         /* setSession( docked, tabbed ) */
605         m_threadDock ->setSession( TRUE, TRUE );
606         m_bbsDock ->setSession( TRUE, FALSE );
607         m_boardDock->setSession( TRUE, TRUE );
608         m_imageDock ->setSession( FALSE, FALSE );
609         m_writeDock ->setSession( FALSE, FALSE );
610         m_naviDock ->setSession( FALSE, FALSE );
611
612         if ( m_boardListAction ) m_boardListAction->setChecked( TRUE );
613         if ( m_subjectListAction ) m_subjectListAction->setChecked( TRUE );
614         if ( m_showImgViewAction ) m_showImgViewAction->setChecked( FALSE );
615         if ( m_showNaviAction ) m_showNaviAction->setChecked( FALSE );
616         if ( m_showWriteDockAction ) m_showWriteDockAction->setChecked( FALSE );
617
618         break;
619
620         /*----------------------------------------*/
621     case 3:
622
623         m_boardDock->manualDock( m_threadDock, KDockWidget::DockCenter, 0 );
624         m_naviDock->manualDock( m_threadDock, KDockWidget::DockCenter, 0 );
625         m_imageDock->manualDock( m_threadDock, KDockWidget::DockCenter, 0 );
626
627         makeDockInvisible( m_imageDock );
628         makeDockInvisible( m_writeDock );
629         makeDockInvisible( m_naviDock );
630
631         /* setSession( docked, tabbed ) */
632         m_threadDock ->setSession( TRUE, TRUE );
633         m_bbsDock ->setSession( TRUE, FALSE );
634         m_boardDock->setSession( TRUE, TRUE );
635         m_imageDock ->setSession( TRUE, TRUE );
636         m_writeDock ->setSession( TRUE, FALSE );
637         m_naviDock ->setSession( TRUE, TRUE );
638
639         if ( m_boardListAction ) m_boardListAction->setChecked( TRUE );
640         if ( m_subjectListAction ) m_subjectListAction->setChecked( TRUE );
641         if ( m_showImgViewAction ) m_showImgViewAction->setChecked( FALSE );
642         if ( m_showNaviAction ) m_showNaviAction->setChecked( FALSE );
643         if ( m_showWriteDockAction ) m_showWriteDockAction->setChecked( FALSE );
644
645         break;
646     }
647
648     m_threadDock->slotShowDock();
649 }
650
651
652 void KitaMainWindow::windowToggleView()
653 {
654     //FIXME: m_boardDock->dockSite() & KDockWidget::DockCenter != 0 igai no toki ha dousuru?
655     kdDebug() << "Do toggle" << endl;
656     if ( !m_boardDock->isVisible()
657             || !m_boardDock->isActiveWindow() ) m_boardDock->slotShowDock();
658     else {
659         m_threadDock->slotShowDock();
660     }
661 }
662
663 void KitaMainWindow::settingsMenuAboutToShow()
664 {
665     m_toolbarAction->setChecked( toolBar() ->isVisible() );
666     m_statusbarAction->setChecked( statusBar() ->isVisible() );
667 }
668
669 void KitaMainWindow::optionsPreferences()
670 {
671     // popup some sort of preference dialog, here
672     KitaPreferences dlg;
673
674     connect( &dlg, SIGNAL( fontChanged( const QFont& ) ),
675              SLOT( setFont( const QFont& ) ) );
676
677     // XXX
678     dlg.setInitialSize( QSize( 600, 400 ) );
679     if ( dlg.exec() ) {
680         // redo your settings
681     }
682 }
683
684 void KitaMainWindow::slotSetMainStatusbar( const QString& statusStr )
685 {
686     // display the text on the statusbar
687     statusBar() ->message( statusStr );
688 }
689
690 void KitaMainWindow::setupView()
691 {
692     /* dummy Main Dock Widget */
693     m_dummyDock = createDockWidget( "dummy", 0L, 0L, "dummy", "dummy" );
694     m_dummyDock->setDockSite( KDockWidget::DockFullSite );
695     m_dummyDock->setEnableDocking( KDockWidget::DockNone );
696     setView( m_dummyDock );
697     setMainDockWidget( m_dummyDock );
698
699     /* Subject View */
700     m_boardDock = new KitaBoardDock( manager(), "subject", 0L, 0L, i18n( "subject" ), i18n( "subject" ) );
701     m_boardTab = m_boardDock->setup();
702     connect( m_boardDock, SIGNAL( checkToggleAction( bool ) ), SLOT( slotCheckSubjectToggleAction( bool ) ) );
703
704     /* Board View */
705     m_bbsDock = new KitaBBSDock( manager(), "board", 0L, 0L, i18n( "board" ), i18n( "board" ) );
706     m_bbsTab = m_bbsDock->setup();
707     connect( m_bbsDock, SIGNAL( checkToggleAction( bool ) ), SLOT( slotCheckBoardToggleAction( bool ) ) );
708
709     /* Thread View */
710     m_threadDock = new KitaThreadDock( manager(), "Thread", 0L, 0L, i18n( "Thread" ), i18n( "Thread" ) );
711     m_threadTab = m_threadDock->setupAsMainView();
712     m_threadDock->setDockSite( KDockWidget::DockFullSite );
713
714     /* KitaNavi */
715     m_naviDock = new KitaThreadDock( manager(), "kitanavi", 0L, 0L, i18n( "KitaNavi" ), i18n( "Navi" ) );
716     m_naviTab = m_naviDock->setupAsKitaNavi();
717     connect( m_naviDock, SIGNAL( checkToggleAction( bool ) ), SLOT( slotCheckNaviToggleAction( bool ) ) );
718
719     if ( !KitaConfig::useKitaNavi() ) m_threadDock ->connectNaviSignals();
720     else m_naviDock->connectNaviSignals();
721
722     /* KitaImgViewer */
723     m_imageDock = new KitaImgDock( manager(), "imgviewer", 0L, 0L, i18n( "Kita Image Viewer" ), i18n( "Image" ) );
724     m_imageTab = m_imageDock->setup();
725     connect( m_imageDock, SIGNAL( checkToggleAction( bool ) ), SLOT( slotCheckImgToggleAction( bool ) ) );
726
727     /* write dock */
728     m_writeDock = new KitaWriteDock( manager(), "Write", 0L, 0L, i18n( "Write" ), i18n( "Write" ) );
729     m_writeTab = m_writeDock->setup();
730     connect( m_writeDock, SIGNAL( checkToggleAction( bool ) ), SLOT( slotCheckWriteToggleAction( bool ) ) );
731
732     /* reset dock status */
733     m_boardListAction = NULL;
734     m_subjectListAction = NULL;
735     m_showImgViewAction = NULL;
736     m_showNaviAction = NULL;
737     m_showWriteDockAction = NULL;
738     resetWindowsDef1();
739 }
740
741 void KitaMainWindow::closeSubjectView()
742 {
743     m_subjectListAction->setChecked( FALSE );
744 }
745
746 void KitaMainWindow::slotCheckBoardToggleAction( bool check )
747 {
748     if ( m_boardListAction ) m_boardListAction->setChecked( check );
749 }
750
751 void KitaMainWindow::slotCheckSubjectToggleAction( bool check )
752 {
753     if ( m_subjectListAction ) m_subjectListAction->setChecked( check );
754 }
755
756 void KitaMainWindow::slotCheckNaviToggleAction( bool check )
757 {
758     if ( m_showNaviAction ) m_showNaviAction->setChecked( check );
759 }
760
761 void KitaMainWindow::slotCheckImgToggleAction( bool check )
762 {
763     if ( m_showImgViewAction ) m_showImgViewAction->setChecked( check );
764 }
765
766
767 void KitaMainWindow::slotCheckWriteToggleAction( bool check )
768 {
769     if ( m_showWriteDockAction ) m_showWriteDockAction->setChecked( check );
770 }
771
772
773 /* open url */ /* public slot */ /* obsolete */
774 void KitaMainWindow::slotOpenURLRequest( const KURL& url, const KParts::URLArgs& args )
775 {
776     slotOpenURLRequestExt( url, args );
777 }
778
779
780 /* open url */
781 /*
782   If mimetype == "kita_open_2chboard", open the board.
783   If mimetype == "kita_open_2chthread",  open the thread.
784   If mimetype == "text/html", open url with web browser.
785   if mimetype == QString::null, use KIO::NetAccess::mimetype to decide mime type of url.
786  
787 */  /* public slot */
788 void KitaMainWindow::slotOpenURLRequestExt(
789     const KURL& url, const KParts::URLArgs& args,
790     QString mimetype,
791     int usr1,
792     const KURL& usrUrl1 )
793 {
794     // FIXME: support be.2ch.net
795     if ( url.host() == "be.2ch.net" && url.path().contains( "/test/p.php", true ) < 1 ) {
796         QMessageBox::warning( this,
797                               "Kita",
798                               i18n( "be.2ch.net is currently not supported." ) );
799         return ;
800     }
801
802     kdDebug() << QString( "Requested OpenURL: \"%1\"" ).arg( url.url() ) << endl;
803     kdDebug() << QString( "content type: \"%1\"" ).arg( args.contentType() ) << endl;
804     kdDebug() << QString( "service type: \"%1\"" ).arg( args.serviceType ) << endl;
805     kdDebug() << QString( "NewTab: %1, reload: %2" )
806     .arg( args.newTab() ? "yes" : "no" )
807     .arg( args.reload ? "yes" : "no" ) << endl;
808
809     /* open 2ch board */
810     /* if usr1 == 1, open the board with new tab. */
811     if ( mimetype == "kita_open_2chboard" ) {
812         bool withNewTab = ( usr1 == 1 );
813         m_boardDock->slotLoadBoard( url, withNewTab );
814         return ;
815     }
816
817     /* open 2ch thread */
818     /* if usr1 == 1, open the thread with new tab. */
819     if ( mimetype == "kita_open_2chthread" ) {
820         bool withNewTab = ( usr1 == 1 || usr1 == 2 );
821         bool byBackground = ( usr1 == 2 );
822         m_threadDock->slotShowThread( url, withNewTab, byBackground );
823         return ;
824     }
825
826     /*  open url with web browser, etc. */
827     if ( mimetype != QString::null ) {
828         if ( KitaConfig::copyOnClick() ) {
829             QClipboard * clipboard = QApplication::clipboard();
830             clipboard->setText( url.prettyURL(), QClipboard::Clipboard );
831             clipboard->setText( url.prettyURL(), QClipboard::Selection );
832         } else {
833             KRun::runURL( url, mimetype );
834         }
835         return ;
836     }
837
838     /* open thread with new thread tab */
839     if ( Kita::DatManager::isThreadEnrolled( url ) ) {
840         m_threadDock->slotShowThread( url, true );
841         return ;
842     }
843
844     /* bmp file */
845     if ( Kita::ImgManager::isBMP( url ) ) {
846         QMessageBox::warning( this,
847                               "Kita",
848                               i18n( "This is a BMP file. It might contain a Troy." ) );
849         return ;
850     }
851
852
853     /* open with image viewer */
854     /* if usr1 == 0, image viewer is hidden. */
855     /* usrUrl1 is datURL.                    */
856     if ( KitaConfig::useImageViewer() ) {
857         if ( Kita::ImgManager::isImgFile( url, FALSE ) ) {
858
859             if ( !usr1 ) m_imageDock->slotHideDock();
860             m_imageDock->slotOpenURL( url, usrUrl1, usr1 );
861             return ;
862         }
863     }
864
865     if ( mimetype == QString::null ) {
866 #if KDE_IS_VERSION( 3, 2, 0 )
867         mimetype = KIO::NetAccess::mimetype( url , this );
868 #else
869         mimetype = KIO::NetAccess::mimetype( url );
870 #endif
871
872     }
873     kdDebug() << QString( "queried MIME type: \"%1\"" ).arg( mimetype ) << endl;
874
875     /* open with kpart */
876     if ( KitaConfig::usePart() ) {
877         if ( KitaConfig::partMimeList().find( mimetype ) != KitaConfig::partMimeList().end() ) {
878             KService::Ptr service = KServiceTypeProfile::preferredService( mimetype, "KParts/ReadOnlyPart" );
879             if ( service ) {
880                 QString libName = QFile::encodeName( service->library() );
881
882                 if ( !KitaConfig::useKitaNavi() ) m_threadDock->slotShowPart( url, libName, mimetype );
883                 else m_naviDock ->slotShowPart( url, libName, mimetype );
884                 return ;
885             }
886         }
887     }
888
889     if ( KitaConfig::copyOnClick() ) {
890         QClipboard * clipboard = QApplication::clipboard();
891         clipboard->setText( url.prettyURL(), QClipboard::Clipboard );
892         clipboard->setText( url.prettyURL(), QClipboard::Selection );
893     } else {
894         KRun::runURL( url, mimetype );
895     }
896 }
897
898
899 void KitaMainWindow::loadCache()
900 {
901     KitaThreadInfo * cache = KitaThreadInfo::getInstance();
902     QString cacheConfigPath = locateLocal( "appdata", "cache" );
903     QFile file( cacheConfigPath );
904     if ( file.open( IO_ReadOnly ) ) {
905         QDataStream stream( &file );
906         stream >> *cache;
907     }
908 }
909
910 void KitaMainWindow::saveCache()
911 {
912     KitaThreadInfo * cache = KitaThreadInfo::getInstance();
913     QString cacheConfigPath = locateLocal( "appdata", "cache" );
914     QFile file( cacheConfigPath );
915     if ( file.open( IO_WriteOnly ) ) {
916         QDataStream stream( &file );
917         stream << *cache;
918     }
919 }
920
921
922 /*!
923     \fn KitaMainWindow::setFont(QFont& font)
924  */
925
926 void KitaMainWindow::setFont( const QFont& font )
927 {
928     m_boardTab->setFont( font );
929     m_bbsTab->setFont( font );
930 }
931
932
933 void KitaMainWindow::setUrl( const KURL& url )
934 {
935     m_urlLine->setText( url.url() );
936 }
937
938 void KitaMainWindow::bookmark( const QString& datURL, bool on )
939 {
940     FavoriteThreads * favorite = FavoriteThreads::getInstance();
941
942     if ( on ) {
943         favorite->insert( datURL );
944     } else {
945         favorite->remove( datURL );
946     }
947     saveFavorites();
948     emit favoritesUpdated();
949 }
950
951 void KitaMainWindow::loadFavorites()
952 {
953     QString favoritesConfigPath = locateLocal( "appdata", "favorites.xml" );
954     QFile file( favoritesConfigPath );
955     if ( file.open( IO_ReadOnly ) ) {
956         QTextStream stream( &file );
957         stream.setEncoding( QTextStream::UnicodeUTF8 );
958
959         QString xml = stream.read();
960         FavoriteThreads::readFromXML( xml );
961     }
962 }
963
964 void KitaMainWindow::saveFavorites()
965 {
966     QString favoritesConfigPath = locateLocal( "appdata", "favorites.xml" );
967     QFile file( favoritesConfigPath );
968     if ( file.open( IO_WriteOnly ) ) {
969         QTextStream stream( &file );
970         stream.setEncoding( QTextStream::UnicodeUTF8 );
971         stream << FavoriteThreads::getInstance() ->toXML();
972     }
973 }
974
975 void KitaMainWindow::loadCompletion()
976 {
977     QString configPath = locateLocal( "appdata", "completion" );
978     KSimpleConfig config( configPath );
979
980     KitaConfig::setNameCompletionItems( config.readListEntry( "name" ) );
981 }
982
983 void KitaMainWindow::saveCompletion()
984 {
985     QString configPath = locateLocal( "appdata", "completion" );
986     KSimpleConfig config( configPath );
987
988     config.writeEntry( "name", KitaConfig::nameCompletion() ->items() );
989     config.sync();
990 }
991
992 void KitaMainWindow::loadStyleSheet()
993 {
994     QString configPath = locateLocal( "appdata", "stylesheet" );
995     QFile file( configPath );
996     if ( file.open( IO_ReadOnly ) ) {
997         QTextStream stream( &file );
998         stream.setEncoding( QTextStream::UnicodeUTF8 );
999
1000         QStringList list;
1001         QString str;
1002
1003         while ( ( str = stream.readLine() ) != QString::null ) {
1004             if ( ! str.isEmpty() ) {
1005                 list << str;
1006             }
1007         }
1008         KitaConfig::setStyleSheetText( list.join( "\n" ) );
1009     }
1010 }
1011
1012 void KitaMainWindow::saveStyleSheet()
1013 {
1014     QString configPath = locateLocal( "appdata", "stylesheet" );
1015     QFile file( configPath );
1016     if ( file.open( IO_WriteOnly ) ) {
1017         QTextStream stream( &file ) ;
1018         stream.setEncoding( QTextStream::UnicodeUTF8 );
1019
1020         stream << KitaConfig::styleSheetText();
1021     }
1022 }
1023
1024 void KitaMainWindow::loadAsciiArt()
1025 {
1026     QString configPath = locateLocal( "appdata", "asciiart" );
1027     QFile file( configPath );
1028     if ( file.open( IO_ReadOnly ) ) {
1029         QTextStream stream( &file );
1030         stream.setEncoding( QTextStream::UnicodeUTF8 );
1031
1032         QStringList list;
1033         QString str;
1034
1035         while ( ( str = stream.readLine() ) != QString::null ) {
1036             if ( ! str.isEmpty() ) {
1037                 list << str;
1038             }
1039         }
1040         KitaConfig::setAsciiArtList( list );
1041     }
1042 }
1043
1044 void KitaMainWindow::saveAsciiArt()
1045 {
1046     QString configPath = locateLocal( "appdata", "asciiart" );
1047     QFile file( configPath );
1048     if ( file.open( IO_WriteOnly ) ) {
1049         QTextStream stream( &file ) ;
1050         stream.setEncoding( QTextStream::UnicodeUTF8 );
1051
1052         QStringList list = KitaConfig::asciiArtList();
1053         QStringList::iterator it;
1054         for ( it = list.begin(); it != list.end(); ++it ) {
1055             stream << ( *it ) << endl;
1056         }
1057     }
1058 }
1059
1060 void KitaMainWindow::loadFavoriteBoards()
1061 {
1062     QString configPath = locateLocal( "appdata", "favorite_boards.xml" );
1063     QFile file( configPath );
1064     if ( file.open( IO_ReadOnly ) ) {
1065         QTextStream stream( &file );
1066         stream.setEncoding( QTextStream::UnicodeUTF8 );
1067
1068         QString xml = stream.read();
1069         Kita::FavoriteBoards::readFromXML( xml );
1070     }
1071 }
1072
1073 void KitaMainWindow::saveFavoriteBoards()
1074 {
1075     QString configPath = locateLocal( "appdata", "favorite_boards.xml" );
1076     QFile file( configPath );
1077     if ( file.open( IO_WriteOnly ) ) {
1078         QTextStream stream( &file );
1079         stream.setEncoding( QTextStream::UnicodeUTF8 );
1080         stream << Kita::FavoriteBoards::toXML();
1081     }
1082 }
1083
1084 void KitaMainWindow::loadAboneIDList()
1085 {
1086     QString configPath = locateLocal( "appdata", "abone_id" );
1087     QFile file( configPath );
1088     if ( file.open( IO_ReadOnly ) ) {
1089         QTextStream stream( &file );
1090         stream.setEncoding( QTextStream::UnicodeUTF8 );
1091
1092         QStringList list;
1093         QString str;
1094
1095         while ( ( str = stream.readLine() ) != QString::null ) {
1096             if ( ! str.isEmpty() ) {
1097                 list << str;
1098             }
1099         }
1100         KitaConfig::setAboneIDList( list );
1101     }
1102 }
1103
1104 void KitaMainWindow::saveAboneIDList()
1105 {
1106     QString configPath = locateLocal( "appdata", "abone_id" );
1107     QFile file( configPath );
1108     if ( file.open( IO_WriteOnly ) ) {
1109         QTextStream stream( &file ) ;
1110         stream.setEncoding( QTextStream::UnicodeUTF8 );
1111
1112         QStringList list = KitaConfig::aboneIDList();
1113         QStringList::iterator it;
1114         for ( it = list.begin(); it != list.end(); ++it ) {
1115             stream << ( *it ) << endl;
1116         }
1117     }
1118 }
1119
1120 void KitaMainWindow::loadAboneNameList()
1121 {
1122     QString configPath = locateLocal( "appdata", "abone_name" );
1123     QFile file( configPath );
1124     if ( file.open( IO_ReadOnly ) ) {
1125         QTextStream stream( &file );
1126         stream.setEncoding( QTextStream::UnicodeUTF8 );
1127
1128         QStringList list;
1129         QString str;
1130
1131         while ( ( str = stream.readLine() ) != QString::null ) {
1132             if ( ! str.isEmpty() ) {
1133                 list << str;
1134             }
1135         }
1136         KitaConfig::setAboneNameList( list );
1137     }
1138 }
1139
1140 void KitaMainWindow::saveAboneNameList()
1141 {
1142     QString configPath = locateLocal( "appdata", "abone_name" );
1143     QFile file( configPath );
1144     if ( file.open( IO_WriteOnly ) ) {
1145         QTextStream stream( &file ) ;
1146         stream.setEncoding( QTextStream::UnicodeUTF8 );
1147
1148         QStringList list = KitaConfig::aboneNameList();
1149         QStringList::iterator it;
1150         for ( it = list.begin(); it != list.end(); ++it ) {
1151             stream << ( *it ) << endl;
1152         }
1153     }
1154 }
1155
1156 void KitaMainWindow::loadAboneWordList()
1157 {
1158     QString configPath = locateLocal( "appdata", "abone_word" );
1159     QFile file( configPath );
1160     if ( file.open( IO_ReadOnly ) ) {
1161         QTextStream stream( &file );
1162         stream.setEncoding( QTextStream::UnicodeUTF8 );
1163
1164         QStringList list;
1165         QString str;
1166
1167         while ( ( str = stream.readLine() ) != QString::null ) {
1168             if ( ! str.isEmpty() ) {
1169                 list << str;
1170             }
1171         }
1172         KitaConfig::setAboneWordList( list );
1173     }
1174 }
1175
1176 void KitaMainWindow::saveAboneWordList()
1177 {
1178     QString configPath = locateLocal( "appdata", "abone_word" );
1179     QFile file( configPath );
1180     if ( file.open( IO_WriteOnly ) ) {
1181         QTextStream stream( &file ) ;
1182         stream.setEncoding( QTextStream::UnicodeUTF8 );
1183
1184         QStringList list = KitaConfig::aboneWordList();
1185         QStringList::iterator it;
1186         for ( it = list.begin(); it != list.end(); ++it ) {
1187             stream << ( *it ) << endl;
1188         }
1189     }
1190 }
1191
1192 void KitaMainWindow::slotSetMainCaption( const QString& captionStr )
1193 {
1194     setCaption( captionStr );
1195 }
1196
1197 void KitaMainWindow::slotEditCopy()
1198 {
1199     QWidget * widget = kapp->focusWidget();
1200
1201     if ( widget ) {
1202         QKeyEvent e( QEvent::KeyPress, Key_C, 'C', ControlButton );
1203         QApplication::sendEvent( widget, &e );
1204     }
1205 }
1206
1207 void KitaMainWindow::login()
1208 {
1209     if ( Kita::Account::login( KitaConfig::userID(), KitaConfig::password() ) ) {
1210         slotSetMainStatusbar( i18n( "Login succeeded." ) );
1211     } else {
1212         slotSetMainStatusbar( i18n( "Login failed." ) );
1213     }
1214 }
1215
1216 void KitaMainWindow::favoritesEdit()
1217 {
1218     FavoritesWindow * window = new FavoritesWindow( this );
1219     window->show();
1220 }
1221
1222 #include "mainwindow.moc"