/*************************************************************************** * Copyright (C) 2005 by Alexander Nemish * * atlanter@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bookreader.h" #include "settings.h" #include "settingsdlg.h" #include "bookmarksdlg.h" namespace { TQStringList listEncodings() { const TQStringList encodings(TDEGlobal::charsets()->availableEncodingNames()); TQStringList availEncodings; for (unsigned int i=0; i < encodings.count(); ++i) { bool found = false; TDEGlobal::charsets()->codecForName(encodings[i], found); if (found) availEncodings << encodings[i]; } return availEncodings; } } BookReader::BookReader() : TDEMainWindow(0, "KBookReader"), m_view(new BookWidget(this)), m_fullScreenAction(0), m_splash(0), m_printer(0) { TQPixmap splash(TDEGlobal::dirs()->findResource("appdata", "themes/default/splash.png")); m_splash = new KSplashScreen(splash); m_splash->show(); // accept dnd setAcceptDrops(true); // tell the TDEMainWindow that this is indeed the main widget setCentralWidget(m_view); // then, setup our actions setupActions(); // and a status bar statusBar()->show(); // Apply the create the main window and ask the mainwindow to // automatically save settings if changed: window size, toolbar // position, icon size, etc. Also to add actions for the statusbar // toolbar, and keybindings if necessary. KStdAction::keyBindings(guiFactory(), TQ_SLOT(configureShortcuts()), actionCollection()); createStandardStatusBarAction(); setStandardToolBarMenuEnabled( true ); KStdAction::configureToolbars(this, TQ_SLOT(configureToolbars() ), actionCollection()); createGUI(TQString(), false); initialGeometrySet(); setAutoSaveSettings(); // allow the view to change the statusbar and caption connect(m_view, TQ_SIGNAL(signalChangeStatusbar(const TQString&)), this, TQ_SLOT(changeStatusbar(const TQString&))); connect(m_view, TQ_SIGNAL(signalChangeCaption(const TQString&)), this, TQ_SLOT(changeCaption(const TQString&))); readSettings(); m_splash->finish(m_view); } BookReader::~BookReader() { writeSettings(); delete m_splash; } void BookReader::load(const KURL& url) { TQString target; // download the contents if(!TDEIO::NetAccess::download(url, target, this)) { KMessageBox::error(this, TDEIO::NetAccess::lastErrorString()); return; } recentFilesAction->addURL(url); setCaption(url.fileName()); m_view->openURL(url); updateBookmarks(); TDEIO::NetAccess::removeTempFile(target); } void BookReader::setupActions() { // KStdAction::openNew(this, TQ_SLOT(fileNew()), actionCollection()); KStdAction::open(this, TQ_SLOT(fileOpen()), actionCollection()); recentFilesAction = KStdAction::openRecent(this, TQ_SLOT(slotURLSelected(const KURL &)), actionCollection()); KStdAction::save(this, TQ_SLOT(fileSave()), actionCollection()); KStdAction::saveAs(this, TQ_SLOT(fileSaveAs()), actionCollection()); KStdAction::print(this, TQ_SLOT(filePrint()), actionCollection()); KStdAction::quit(kapp, TQ_SLOT(quit()), actionCollection()); KStdAction::firstPage(this, TQ_SLOT(gotoFirstPage()), actionCollection()); KStdAction::prior(this, TQ_SLOT(prevPage()), actionCollection()); KStdAction::next(this, TQ_SLOT(nextPage()), actionCollection()); KStdAction::lastPage(this, TQ_SLOT(gotoLastPage()), actionCollection()); KStdAction::addBookmark(this, TQ_SLOT(addBookmark()), actionCollection()); KStdAction::editBookmarks(this, TQ_SLOT(editBookmarks()), actionCollection()); KStdAction::gotoPage(this, TQ_SLOT(gotoPage()), actionCollection()); m_fullScreenAction = KStdAction::fullScreen(this, TQ_SLOT(fullScreen()), actionCollection(), this); KStdAction::preferences(this, TQ_SLOT(optionsPreferences()), actionCollection()); TDEConfig *config = kapp->config(); recentFilesAction->loadEntries(config); // this doesn't do anything useful. it's just here to illustrate // how to insert a custom menu and menu item /* TDEAction *custom = new TDEAction( i18n( "Cus&tom Menuitem" ), 0, this, TQ_SLOT( optionsPreferences() ), actionCollection(), "custom_action" );*/ } void BookReader::saveProperties(TDEConfig *config) { // the 'config' object points to the session managed // config file. anything you write here will be available // later when this app is restored if (!m_view->currentURL().isEmpty()) { config->writeEntry("lastURL", m_view->currentURL()); config->writeEntry("currentPage", m_view->currentPage()); } } void BookReader::readProperties(TDEConfig */*config*/) { // the 'config' object points to the session managed // config file. this function is automatically called whenever // the app is being restored. read in here whatever you wrote // in 'saveProperties' // TQString url = config->readPathEntry("lastURL"); // int currentPage = config->readEntry("currentPage").toInt(); /* Disable forawhile if (!url.isEmpty()) { m_view->openURL(KURL(url)); m_view->setCurrentPage(currentPage); } */ } void BookReader::dragEnterEvent(TQDragEnterEvent *event) { // accept uri drops only event->accept(KURLDrag::canDecode(event)); } void BookReader::dropEvent(TQDropEvent *event) { // this is a very simplistic implementation of a drop event. we // will only accept a dropped URL. the TQt dnd code can do *much* // much more, so please read the docs there KURL::List urls; // see if we can decode a URI.. if not, just ignore it if (KURLDrag::decode(event, urls) && !urls.isEmpty()) { // okay, we have a URI.. process it const KURL & url = urls.first(); // load in the file load(url); } } void BookReader::fileOpen() { // this slot is called whenever the File->Open menu is selected, // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar // button is clicked /* // this brings up the generic open dialog KURL url = KURLRequesterDlg::getURL(TQString(), this, i18n("Open Location") ); */ // standard filedialog KEncodingFileDialog::Result res = KEncodingFileDialog::getOpenURLAndEncoding( listEncodings()[Settings::defaultEncoding()]); KURL url = res.URLs.front(); m_view->setEncoding(res.encoding); if (!url.isEmpty()) load(url); } void BookReader::fileSave() { // this slot is called whenever the File->Save menu is selected, // the Save shortcut is pressed (usually CTRL+S) or the Save toolbar // button is clicked // save the current file } void BookReader::fileSaveAs() { // this slot is called whenever the File->Save As menu is selected, KURL file_url = KFileDialog::getSaveURL(); if (!file_url.isEmpty() && file_url.isValid()) { // save your info, here } } void BookReader::filePrint() { // this slot is called whenever the File->Print menu is selected, // the Print shortcut is pressed (usually CTRL+P) or the Print toolbar // button is clicked if (!m_printer) m_printer = new KPrinter; if (m_printer->setup(this)) { // setup the printer. with TQt, you always "print" to a // TQPainter.. whether the output medium is a pixmap, a screen, // or paper TQPainter p; p.begin(m_printer); // we let our view do the actual printing TQPaintDeviceMetrics metrics(m_printer); //m_view->print( &p, metrics.height(), metrics.width() ); // and send the result to the printer p.end(); } } void BookReader::optionsPreferences() { if (TDEConfigDialog::showDialog("settings")) return ; TDEConfigDialog *dialog = new TDEConfigDialog(this, "settings", Settings::self(), KDialogBase::IconList); SettingsWidget *general = new SettingsWidget(0, "General"); const TQStringList encodings(listEncodings()); TQString curEncoding(encodings[Settings::defaultEncoding()]); if (curEncoding.isEmpty()) curEncoding = TQString::fromLatin1(TDEGlobal::locale()->encoding()); general->kcfg_DefaultEncoding->clear(); general->kcfg_DefaultEncoding->insertStringList(encodings); for (unsigned int i=0; i < encodings.count(); ++i) if (encodings[i] == curEncoding) general->kcfg_DefaultEncoding->setCurrentItem(i); dialog->addPage(general, i18n("General"), "settings"); connect(dialog, TQ_SIGNAL(settingsChanged()), this, TQ_SLOT(loadSettings())); dialog->show(); } void BookReader::changeStatusbar(const TQString& text) { // display the text on the statusbar statusBar()->message(text); } void BookReader::changeCaption(const TQString& text) { // display the text on the caption setCaption(text); } void BookReader::loadSettings() { m_view->setFont(Settings::font()); m_view->setParaOffset(Settings::paraOffset()); m_view->setEncoding(Settings::defaultEncoding()); } void BookReader::slotURLSelected(const KURL & url) { load(url); } bool BookReader::queryExit() { writeSettings(); return true; } void BookReader::writeSettings() { TDEConfig * config = kapp->config(); config->writeEntry("size", m_view->size()); config->writeEntry("lastURL", m_view->currentURL()); config->writeEntry("lastURLPage", m_view->currentPage()); recentFilesAction->saveEntries(TDEGlobal::config()); } void BookReader::readSettings() { recentFilesAction->loadEntries(TDEGlobal::config()); recentFilesAction->setEnabled(true); // force enabling m_view->setParaOffset(Settings::paraOffset()); m_view->setEncodings(listEncodings()); m_view->setEncoding(Settings::defaultEncoding()); if (Settings::loadLastUrl()) { loadLastUrl(); } } void BookReader::fullScreen() { if (m_fullScreenAction->isChecked()) { menuBar()->hide(); setWindowState(windowState() | WindowFullScreen); } else { menuBar()->show(); setWindowState(windowState() & ~WindowFullScreen); } } void BookReader::loadLastUrl() { TDEConfig * config = kapp->config(); TQSize size = config->readSizeEntry("size"); lastURL = config->readEntry("lastURL"); connect(m_view, TQ_SIGNAL(loadingFinished()), this, TQ_SLOT(loadLastURLSetPage())); if (!lastURL.isEmpty()) { // kdDebug() << "loadLastUrl: initial size = " << m_view->size() << endl; m_view->resize(size); // kdDebug() << "loadLastUrl: resize = " << m_view->size() << endl; m_view->setupPageSize(); // kdDebug() << "render = 1" << endl; load(lastURL); } } void BookReader::loaded(int loaded) { //m_loaded = loaded; m_splash->message(tr("Loading: %1 - %2%").arg(lastURL.fileName()).arg(loaded)); } void BookReader::gotoFirstPage() { m_view->firstPage(); } void BookReader::nextPage() { m_view->nextPage(); } void BookReader::prevPage() { m_view->prevPage(); } void BookReader::gotoLastPage( ) { m_view->lastPage(); } void BookReader::gotoPage() { bool isOk; int page = KInputDialog::getInteger(tr("Goto page"), tr("Page number"), m_view->currentPage(), 1, m_view->pageCount(), 1, &isOk); m_view->setCurrentPage(page - 1); } void BookReader::loadLastURLSetPage() { int lastURLPage = kapp->config()->readNumEntry("lastURLPage"); m_view->setCurrentPage(lastURLPage); } void BookReader::addBookmark() { bool isOk; TQString name = KInputDialog::getText(tr("Add bookmark"), tr("Bookmark name"), tr("Here"), &isOk); if (isOk) { m_view->addBookmark(name); updateBookmarks(); } } /*! \fn BookReader::updateBookmarks() */ void BookReader::updateBookmarks() { unplugActionList("my_bookmarks"); m_bookmarkActions.clear(); m_bookmarkActions.setAutoDelete(true); const Bookmarks & bms = m_view->bookmarks(); TQSignalMapper *bookmarkMapper = new TQSignalMapper(this); connect(bookmarkMapper, TQ_SIGNAL(mapped(int)), this, TQ_SLOT(gotoBookmark(int))); for (Bookmarks::size_type i = 0; i < 9 && i < bms.size(); ++i) { const Bookmark & bm = bms[i]; TDEAction * action = new TDEAction(bm.name(), ALT+Key_1 + i); connect(action, TQ_SIGNAL(activated()), bookmarkMapper, TQ_SLOT(map())); m_bookmarkActions.append(action); bookmarkMapper->setMapping(action, i); } plugActionList("my_bookmarks", m_bookmarkActions); } /*! \fn BookReader::gotoBookmark(int index) */ void BookReader::gotoBookmark(int index) { const Bookmarks & bms = m_view->bookmarks(); assert(index < bms.size()); unsigned int page = bms[index].page(); m_view->setCurrentPage(page); } /*! \fn BookReader::editBookmarks() */ void BookReader::editBookmarks() { /// @todo implement me BookmarksDlg dialog(m_view->bookmarks()); if (dialog.exec() == TQDialog::Accepted) { m_view->setBookmarks(dialog.bookmarks()); updateBookmarks(); } } #include "bookreader.moc"