OSDN Git Service

1d74b0753116e4f06e8f301e97bc77dad9caaadc
[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 <QtCore/QEvent>
14 #include <QtCore/QFile>
15 #include <QtGui/QBoxLayout>
16 #include <QtGui/QKeyEvent>
17 #include <QtGui/QSplitter>
18
19 #include <kaction.h>
20 #include <kactioncollection.h>
21 #include <kapplication.h>
22 #include <kconfig.h>
23 #include <kedittoolbar.h>
24 #include <kglobal.h>
25 #include <klineedit.h>
26 #include <klocale.h>
27 #include <kmenubar.h>
28 #include <kshortcutsdialog.h>
29 #include <kstandarddirs.h>
30 #include <kstatusbar.h>
31 #include <ktoggleaction.h>
32 #include <ktoolbar.h>
33 #include <kurl.h>
34 #include <kxmlguifactory.h>
35
36 #include "bbstabwidget.h"
37 #include "boardtabwidget.h"
38 #include "threadtabwidget.h"
39 #include "viewmediator.h"
40 #include "writetabwidget.h"
41 #include "libkita/abone.h"
42 #include "libkita/account.h"
43 #include "libkita/accountconfig.h"
44 #include "libkita/asciiart.h"
45 #include "libkita/colorconfig.h"
46 #include "libkita/datmanager.h"
47 #include "libkita/favoriteboards.h"
48 #include "libkita/favoritethreads.h"
49 #include "libkita/globalconfig.h"
50 #include "libkita/kita_misc.h"
51 #include "libkita/threadinfo.h"
52 #include "libkita/writeconfig.h"
53 #include "prefs/preferences.h"
54
55 using namespace Kita;
56
57 MainWindow::MainWindow() : KXmlGuiWindow(0), m_prefDialog(0)
58 {
59     // accept dnd
60     setAcceptDrops(true);
61
62     // setup view, dock
63     setupView();
64
65     // then, setup our actions
66     setupActions();
67
68     // load cache
69     loadCache();
70
71     // load ascii art
72     AsciiArtConfig::self()->readConfig();
73     if (AsciiArtConfig::self()->asciiArtList().isEmpty()) {
74         loadAsciiArt();
75     }
76
77     // load abone lists
78     AboneConfig::self()->readConfig();
79     if (AboneConfig::self()->aboneIDList().isEmpty()) {
80         loadAboneIDList();
81     }
82
83     if (AboneConfig::self()->aboneNameList().isEmpty()) {
84         loadAboneNameList();
85     }
86
87     if (AboneConfig::self()->aboneWordList().isEmpty()) {
88         loadAboneWordList();
89     }
90
91     // and a status bar
92     statusBar() ->show();
93
94     // for compativility
95     loadCompletion();
96
97     AccountConfig::self()->readConfig();
98     ColorConfig::self()->readConfig();
99     GlobalConfig::self()->readConfig();
100     WriteConfig::self()->readConfig();
101
102     // apply the saved mainwindow settings, if any, and ask the mainwindow
103     // to automatically save settings if changed: window size, toolbar
104     // position, icon size, etc.
105     setAutoSaveSettings();
106
107     // set list font
108     setFont(GlobalConfig::font());
109
110     // allow the view to change the statusbar and caption
111     connect(m_urlLine, SIGNAL(returnPressed()),
112              SLOT(slotUrlLine()));
113
114     QMenu* settingsPopup = static_cast<QMenu *>(factory() ->container("settings", this));
115     connect(settingsPopup, SIGNAL(aboutToShow()),
116              SLOT(settingsMenuAboutToShow()));
117
118     // load favorite boards;
119     loadFavoriteBoards();
120
121     // load boad list
122     {
123         QString configPath = KStandardDirs::locateLocal("appdata", "board_list");
124         if (QFile::exists(configPath)) {
125             m_bbsTab->showBoardList();
126             m_bbsTab->loadOpened();
127         } else {
128             m_bbsTab->updateBoardList();
129         }
130     }
131
132     // load favorites
133     loadFavorites();
134
135     // update favorite list
136     ViewMediator::getInstance()->updateFavoriteListView();
137
138     if (AccountConfig::autoLogin()) {
139         login();
140     }
141 }
142
143 MainWindow::~MainWindow()
144 {
145     AboneConfig::self()->writeConfig();
146
147     AsciiArtConfig::self()->writeConfig();
148
149     saveFavoriteBoards();
150
151     saveFavorites();
152
153     saveCache();
154
155     saveMainWindowSettings(KGlobal::config().data()->group("MainWindow"));
156
157     AccountConfig::self()->writeConfig();
158     ColorConfig::self()->writeConfig();
159     GlobalConfig::self()->writeConfig();
160     WriteConfig::self()->writeConfig();
161
162     DatManager::deleteAllDatInfo();
163 }
164
165 void MainWindow::load(const KUrl& url)
166 {
167     setCaption(url.url());
168 }
169
170 void MainWindow::bookmark(const QString& datUrl, bool on)
171 {
172     FavoriteThreads * favorite = FavoriteThreads::getInstance();
173
174     on ? favorite->insert(datUrl) : favorite->remove(datUrl);
175     saveFavorites();
176     ViewMediator::getInstance()->updateFavoriteListView();
177 }
178
179 void MainWindow::login()
180 {
181     if (Account::login(AccountConfig::userID(), AccountConfig::password())) {
182         setMainStatus(i18nc("@info:status", "Login succeeded."));
183     } else {
184         setMainStatus(i18nc("@info:status", "Login failed."));
185     }
186 }
187
188 void MainWindow::newToolbarConfig()
189 {
190     // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
191     // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
192     applyMainWindowSettings(KGlobal::config().data()->group("MainWindow"));
193 }
194
195 void MainWindow::optionsShowToolbar()
196 {
197     // this is all very cut and paste code for showing/hiding the
198     // toolbar
199     if (m_toolbarAction->isChecked()) {
200         toolBar() ->show();
201     } else {
202         toolBar() ->hide();
203     }
204 }
205
206 void MainWindow::optionsShowStatusbar()
207 {
208     // this is all very cut and paste code for showing/hiding the
209     // statusbar
210     if (m_statusbarAction->isChecked()) {
211         statusBar() ->show();
212     } else {
213         statusBar() ->hide();
214     }
215 }
216
217 void MainWindow::optionsConfigureKeys()
218 {
219     KShortcutsDialog::configure(actionCollection());
220 }
221
222 void MainWindow::optionsConfigureToolbars()
223 {
224     // use the standard toolbar editor
225     KEditToolBar dlg(factory());
226     connect(&dlg, SIGNAL(newToolbarConfig()),
227              SLOT(newToolbarConfig()));
228     dlg.exec();
229 }
230
231 void MainWindow::optionsPreferences()
232 {
233     if (m_prefDialog == 0) {
234         m_prefDialog = new Preferences(this);
235         m_prefDialog->load();
236         connect(m_prefDialog, SIGNAL(fontChanged(const QFont&)),
237                  SLOT(setFont(const QFont&)));
238         m_prefDialog->show();
239     } else {
240         m_prefDialog->show();
241         m_prefDialog->raise();
242     }
243 }
244
245 void MainWindow::settingsMenuAboutToShow()
246 {
247     m_toolbarAction->setChecked(toolBar() ->isVisible());
248     m_statusbarAction->setChecked(statusBar() ->isVisible());
249 }
250
251 void MainWindow::setFont(const QFont& font)
252 {
253     m_boardTab->setFont(font);
254     m_bbsTab->setFont(font);
255 }
256
257 void MainWindow::setUrl(const KUrl& url)
258 {
259     m_urlLine->setText(url.url());
260 }
261
262 void MainWindow::slotEditCopy()
263 {
264     QWidget * widget = KApplication::kApplication()->focusWidget();
265
266     if (widget) {
267         QKeyEvent e(QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier);
268         QApplication::sendEvent(widget, &e);
269     }
270 }
271
272 void MainWindow::setMainStatus(const QString& statusStr)
273 {
274     // display the text on the statusbar
275     statusBar()->showMessage(statusStr);
276 }
277
278 void MainWindow::slotUrlLine()
279 {
280     KUrl url = m_urlLine->text();
281     KUrl datUrl = getDatUrl(url);
282     m_threadTab->slotShowMainThread(datUrl);
283 }
284
285 //
286 // private method
287 //
288
289 void MainWindow::setupActions()
290 {
291     KStandardAction::quit(this, SLOT(close()), actionCollection());
292     KStandardAction::copy(this, SLOT(slotEditCopy()), actionCollection());
293
294     setStandardToolBarMenuEnabled(true);
295
296     m_toolbarAction
297         = new KToggleAction(i18nc("@action:inmenu", "Show Toolbar"), this);
298     actionCollection()->addAction("toolBar", m_toolbarAction);
299     connect(m_toolbarAction, SIGNAL(toggled(bool)),
300             SLOT(optionsShowToolbar()));
301
302     m_statusbarAction = KStandardAction::showStatusbar(this,
303                         SLOT(optionsShowStatusbar()),
304                         actionCollection());
305
306     m_urlLine = new KLineEdit;
307     KAction* urlLineAction = new KAction(this);
308     urlLineAction->setDefaultWidget(m_urlLine);
309     urlLineAction->setText(i18nc("@action:intoolbar", "Location Bar"));
310     actionCollection()->addAction("url_line_action", urlLineAction);
311     connect(urlLineAction, SIGNAL(triggered()), this, SLOT(slotUrlLine()));
312
313     KStandardAction::keyBindings(this, SLOT(optionsConfigureKeys()),
314             actionCollection());
315     KStandardAction::configureToolbars(this, SLOT(optionsConfigureToolbars()),
316             actionCollection());
317     KStandardAction::preferences(this, SLOT(optionsPreferences()),
318             actionCollection());
319
320     KAction* loadBoardAction
321         = actionCollection()->addAction("load_board_list");
322     loadBoardAction->setText(i18nc("@action:inmenu", "Load Board List"));
323     connect(loadBoardAction, SIGNAL(triggered()),
324             m_bbsTab, SLOT(updateBoardList()));
325
326     KAction* loginAction = actionCollection()->addAction("login");
327     loginAction->setText(i18nc("@action:inmenu Login menu", "Login"));
328     connect(loginAction, SIGNAL(triggered()), m_bbsTab, SLOT(login()));
329
330     setXMLFile("kitaui.rc");
331     KXmlGuiWindow::createGUI();
332     factory()->addClient(m_bbsTab);
333     factory()->addClient(m_boardTab);
334     factory()->addClient(m_threadTab);
335     factory()->addClient(m_writeTab);
336 }
337
338 void MainWindow::setupView()
339 {
340     ViewMediator::getInstance()->setMainWindow(this);
341
342     QWidget* mainWidget = new QWidget(this);
343
344     QBoxLayout* mainLayout = new QVBoxLayout(mainWidget);
345     QSplitter* hsplit = new QSplitter(mainWidget);
346     mainLayout->addWidget(hsplit);
347
348     m_bbsTab = new BBSTabWidget(hsplit);
349
350     QSplitter* vsplit = new QSplitter(Qt::Vertical, hsplit);
351
352     m_boardTab = new BoardTabWidget(vsplit);
353     ViewMediator::getInstance()->setBoardTabWidget(m_boardTab);
354
355     m_threadTab = new ThreadTabWidget(vsplit);
356     ViewMediator::getInstance()->setThreadTabWidget(m_threadTab);
357
358     hsplit->setSizes(QList<int>() << 100 << 500);
359     vsplit->setSizes(QList<int>() << 200 << 300);
360
361     setCentralWidget(mainWidget);
362
363     /* write dock */
364     m_writeTab = new WriteTabWidget(0);
365     ViewMediator::getInstance()->setWriteTabWidget(m_writeTab);
366 }
367
368 void MainWindow::loadCache()
369 {
370     ThreadInfo * cache = ThreadInfo::getInstance();
371     QString cacheConfigPath = KStandardDirs::locateLocal("appdata", "cache");
372     QFile file(cacheConfigPath);
373     if (file.open(QIODevice::ReadOnly)) {
374         QDataStream stream(&file);
375         stream >> *cache;
376     }
377 }
378
379 void MainWindow::saveCache()
380 {
381     ThreadInfo * cache = ThreadInfo::getInstance();
382     QString cacheConfigPath = KStandardDirs::locateLocal("appdata", "cache");
383     QFile file(cacheConfigPath);
384     if (file.open(QIODevice::WriteOnly)) {
385         QDataStream stream(&file);
386         stream << *cache;
387     }
388 }
389
390 void MainWindow::loadFavorites()
391 {
392     QString favoritesConfigPath = KStandardDirs::locateLocal("appdata", "favorites.xml");
393     QFile file(favoritesConfigPath);
394     if (file.open(QIODevice::ReadOnly)) {
395         QTextStream stream(&file);
396         stream.setCodec("UTF-8");
397
398         QString xml = stream.readAll();
399         FavoriteThreads::readFromXML(xml);
400     }
401 }
402
403 void MainWindow::saveFavorites()
404 {
405     QString favoritesConfigPath
406         = KStandardDirs::locateLocal("appdata", "favorites.xml");
407     QFile file(favoritesConfigPath);
408     if (file.open(QIODevice::WriteOnly)) {
409         QTextStream stream(&file);
410         stream.setCodec("UTF-8");
411         stream << FavoriteThreads::getInstance()->toXML();
412     }
413 }
414
415 void MainWindow::loadFavoriteBoards()
416 {
417     QString configPath = KStandardDirs::locateLocal("appdata", "favorite_boards.xml");
418     QFile file(configPath);
419     if (file.open(QIODevice::ReadOnly)) {
420         QTextStream stream(&file);
421         stream.setCodec("UTF-8");
422
423         QString xml = stream.readAll();
424         FavoriteBoards::readFromXML(xml);
425     }
426 }
427
428 void MainWindow::saveFavoriteBoards()
429 {
430     QString configPath = KStandardDirs::locateLocal("appdata", "favorite_boards.xml");
431     QFile file(configPath);
432     if (file.open(QIODevice::WriteOnly)) {
433         QTextStream stream(&file);
434         stream.setCodec("UTF-8");
435         stream << FavoriteBoards::toXML();
436     }
437 }
438
439 void MainWindow::loadCompletion()
440 {
441     QString configPath = KStandardDirs::locateLocal("appdata", "completion");
442     KConfig config(configPath);
443
444     GlobalConfig::setNameCompletionList(
445             config.group("").readEntry("name", QStringList()));
446 }
447
448 void MainWindow::loadAsciiArt()
449 {
450     QString configPath = KStandardDirs::locateLocal("appdata", "asciiart");
451     QFile file(configPath);
452     if (file.open(QIODevice::ReadOnly)) {
453         QTextStream stream(&file);
454         stream.setCodec("UTF-8");
455
456         QStringList list;
457         QString str;
458
459         while (!(str = stream.readLine()).isEmpty()) {
460             if (! str.isEmpty()) {
461                 list << str;
462             }
463         }
464         AsciiArtConfig::setAsciiArtList(list);
465     }
466 }
467
468 void MainWindow::loadAboneIDList()
469 {
470     QString configPath = KStandardDirs::locateLocal("appdata", "abone_id");
471     QFile file(configPath);
472     if (file.open(QIODevice::ReadOnly)) {
473         QTextStream stream(&file);
474         stream.setCodec("UTF-8");
475
476         QStringList list;
477         QString str;
478
479         while (!(str = stream.readLine()).isEmpty()) {
480             if (! str.isEmpty()) {
481                 list << str;
482             }
483         }
484         AboneConfig::setAboneIDList(list);
485     }
486 }
487
488 void MainWindow::loadAboneNameList()
489 {
490     QString configPath = KStandardDirs::locateLocal("appdata", "abone_name");
491     QFile file(configPath);
492     if (file.open(QIODevice::ReadOnly)) {
493         QTextStream stream(&file);
494         stream.setCodec("UTF-8");
495
496         QStringList list;
497         QString str;
498
499         while (!(str = stream.readLine()).isEmpty()) {
500             if (! str.isEmpty()) {
501                 list << str;
502             }
503         }
504         AboneConfig::setAboneNameList(list);
505     }
506 }
507
508 void MainWindow::loadAboneWordList()
509 {
510     QString configPath = KStandardDirs::locateLocal("appdata", "abone_word");
511     QFile file(configPath);
512     if (file.open(QIODevice::ReadOnly)) {
513         QTextStream stream(&file);
514         stream.setCodec("UTF-8");
515
516         QStringList list;
517         QString str;
518
519         while (!(str = stream.readLine()).isEmpty()) {
520             if (! str.isEmpty()) {
521                 list << str;
522             }
523         }
524         AboneConfig::setAboneWordList(list);
525     }
526 }