Now the systrayicon change it's color when a download is in progress. I simply change...
[kdenetwork.git] / kdict / queryview.cpp
bloba2674d68e7069d6ad362f40274ecb5dd21f20c80
1 /* -------------------------------------------------------------
3 queryview.cpp (part of The KDE Dictionary Client)
5 Copyright (C) 2000-2001 Christian Gebauer <gebauer@kde.org>
7 This file is distributed under the Artistic License.
8 See LICENSE for details.
10 -------------------------------------------------------------
12 BrowseData data structure used for caching definitions
13 DictHTMLPart handling of middle mouse button clicks
14 QueryView widget that displays the definitions
16 ------------------------------------------------------------- */
18 #include <qclipboard.h>
19 #include <qtimer.h>
21 #include <kfiledialog.h>
22 #include <ktempfile.h>
23 #include <kio/netaccess.h>
24 #include <kcursor.h>
25 #include <kpopupmenu.h>
26 #include <kmessagebox.h>
27 #include <klocale.h>
28 #include <khtml_events.h>
29 #include <khtmlview.h>
31 #include "actions.h"
32 #include "options.h"
33 #include "dict.h"
34 #include "queryview.h"
35 #include <kapplication.h>
36 #include <kiconloader.h>
39 //******** SaveHelper *******************************************
41 QString SaveHelper::lastPath;
43 SaveHelper::SaveHelper(const QString &saveName, const QString &filter, QWidget *parent)
44 : p_arent(parent), s_aveName(saveName), f_ilter(filter), file(0), tmpFile(0)
49 SaveHelper::~SaveHelper()
51 if (file) { // local filesystem, just close the file
52 delete file;
53 } else
54 if (tmpFile) { // network location, initiate transaction
55 tmpFile->close();
56 if (KIO::NetAccess::upload(tmpFile->name(),url, p_arent) == false)
57 KMessageBox::error(global->topLevel, i18n("Unable to save remote file."));
58 tmpFile->unlink(); // delete temp file
59 delete tmpFile;
64 QFile* SaveHelper::getFile(const QString &dialogTitle)
66 url = KFileDialog::getSaveURL(lastPath+s_aveName,f_ilter,p_arent,dialogTitle);
68 if (url.isEmpty())
69 return 0;
71 lastPath = url.url(-1);
72 lastPath.truncate(lastPath.length()-url.fileName().length());
74 if (url.isLocalFile()) {
75 if (QFileInfo(url.path()).exists() &&
76 (KMessageBox::warningContinueCancel(global->topLevel,
77 i18n("A file named %1 already exists.\nDo you want to replace it?").arg(url.path()),
78 dialogTitle, i18n("&Replace")) != KMessageBox::Continue)) {
79 return 0;
82 file = new QFile(url.path());
83 if(!file->open(IO_WriteOnly)) {
84 KMessageBox::error(global->topLevel, i18n("Unable to save file."));
85 delete file;
86 file = 0;
88 return file;
89 } else {
90 tmpFile = new KTempFile();
91 if (tmpFile->status()!=0)
92 KMessageBox::error(global->topLevel, i18n("Unable to create temporary file.")); {
93 delete tmpFile;
94 tmpFile = 0;
95 return 0;
97 return tmpFile->file();
102 //**** BrowseData ****************************************************
105 BrowseData::BrowseData(const QString &Nhtml, const QString &NqueryText)
106 : html(Nhtml),queryText(NqueryText),xPos(0),yPos(0)
110 //********* DictHTMLPart ******************************************
112 DictHTMLPart::DictHTMLPart(QWidget *parentWidget, const char *widgetname)
113 : KHTMLPart(parentWidget,widgetname)
117 DictHTMLPart::~DictHTMLPart()
121 void DictHTMLPart::khtmlMouseReleaseEvent(khtml::MouseReleaseEvent *event)
123 if (event->qmouseEvent()->button()==MidButton)
124 emit(middleButtonClicked());
125 else
126 KHTMLPart::khtmlMouseReleaseEvent(event);
130 //********* QueryView ******************************************
133 QueryView::QueryView(QWidget *_parent)
134 : QVBox( _parent), actBack(0L), actForward(0L), actQueryCombo(0L), browsePos(0), isRendering(false)
136 browseList.setAutoDelete(true);
138 part=new DictHTMLPart(this);
139 part->setDNDEnabled(false);
140 part->setJScriptEnabled(false);
141 part->setJavaEnabled(false);
142 part->setURLCursor(KCursor::handCursor());
143 setFocusPolicy(QWidget::NoFocus);
144 connect(part, SIGNAL(completed()), SLOT(partCompleted()));
145 connect(part, SIGNAL(middleButtonClicked()), SLOT(middleButtonClicked()));
146 rightBtnMenu = new KPopupMenu(this);
147 connect(part,SIGNAL(popupMenu(const QString &, const QPoint &)),this,SLOT(buildPopupMenu(const QString &, const QPoint &)));
148 connect(part->browserExtension(),SIGNAL(openURLRequest(const KURL &,const KParts::URLArgs &)),
149 this,SLOT(slotURLRequest(const KURL &,const KParts::URLArgs &)));
150 connect(part->browserExtension(),SIGNAL(enableAction(const char *,bool)),this,SLOT(enableAction(const char *,bool)));
151 QTimer::singleShot( 0, this, SLOT(optionsChanged()) );
152 connect(interface,SIGNAL(resultReady(const QString &, const QString &)), SLOT(resultReady(const QString &, const QString &)));
156 QueryView::~QueryView()
160 void QueryView::setActions(KToolBarPopupAction* NactBack, KToolBarPopupAction* NactForward, DictComboAction* NactQueryCombo)
162 actBack = NactBack;
163 connect(actBack->popupMenu(),SIGNAL(activated(int)),SLOT(browseBack(int)));
164 actForward = NactForward;
165 connect(actForward->popupMenu(),SIGNAL(activated(int)),SLOT(browseForward(int)));
166 actQueryCombo = NactQueryCombo;
170 bool QueryView::browseBackPossible() const
172 return (browsePos > 0)? true:false;
176 bool QueryView::browseForwardPossible() const
178 return (browsePos+1 < browseList.count()) ? true:false;
182 void QueryView::optionsChanged()
184 saveCurrentResultPos();
186 currentHTMLHeader = QString("<html><head><style type=\"text/css\">\n");
187 currentHTMLHeader += QString("body { background-color:%1; color:%2; }\n").arg(global->backgroundColor().name()).arg(global->textColor().name());
188 currentHTMLHeader += QString("a:link, a:active { color:%1; text-decoration:none; }\n").arg(global->linksColor().name());
189 currentHTMLHeader += QString("a:visited { color:%1; text-decoration:none; }\n").arg(global->visitedLinksColor().name());
190 currentHTMLHeader += QString("a:hover { color:%1; text-decoration:underline; }\n").arg(global->linksColor().name());
191 currentHTMLHeader += QString("p.heading { margin-left:0mm; margin-top:2mm; margin-bottom:2mm; padding:1mm; background-color:%1; color:%2; font-family:%3; font-size:%4pt; ").arg(global->headingsBackgroundColor().name()).arg(global->headingsTextColor().name()).arg(global->headingsFont().family()).arg(global->headingsFont().pointSize());
192 if (global->headingsFont().italic())
193 currentHTMLHeader += QString("font-style:italic; ");
194 if (global->headingsFont().bold())
195 currentHTMLHeader += QString("font-weight:bold; ");
196 currentHTMLHeader += QString("}\n");
197 currentHTMLHeader += QString("p.definition { margin-left:1.5mm; margin-top:2mm; margin-bottom:2mm;}\n");
198 currentHTMLHeader += QString("table { margin-left:1.5mm; margin-top:2mm; margin-bottom:2mm;}\n");
199 currentHTMLHeader += QString("pre { font-family:%1; font-size:%2pt; ").arg(global->textFont().family()).arg(global->textFont().pointSize());
200 if (global->textFont().italic())
201 currentHTMLHeader += QString("font-style:italic; ");
202 if (global->textFont().bold())
203 currentHTMLHeader += QString("font-weight:bold; ");
204 currentHTMLHeader += QString("}\n");
205 currentHTMLHeader += QString("</style></head>\n");
207 showResult(); // apply changes directly
211 void QueryView::stop()
213 if (isRendering == true) {
214 part->closeURL();
215 isRendering = false;
216 emit(renderingStopped());
221 // print current result
222 void QueryView::printQuery()
224 part->view()->print();
228 // save the current result in an .html file
229 void QueryView::saveQuery()
231 if (!browseList.isEmpty()) {
232 BrowseData* brw = browseList.at(browsePos);
233 QString fName = brw->queryText+".html";
234 fName.replace(QRegExp("[\\s/]"),"_");
235 SaveHelper helper(fName,"*.html",global->topLevel);
236 QFile *file = helper.getFile(QString::null);
238 if (file) {
239 QTextStream stream(file);
240 stream.setEncoding(QTextStream::Locale);
241 stream << currentHTMLHeader+brw->html;
247 void QueryView::browseBack()
249 if (browseBackPossible()) {
250 saveCurrentResultPos();
251 browsePos--;
252 actQueryCombo->setEditText(browseList.at(browsePos)->queryText);
253 showResult();
254 updateBrowseActions();
259 void QueryView::browseForward()
261 if (browseForwardPossible()) {
262 saveCurrentResultPos();
263 browsePos++;
264 actQueryCombo->setEditText(browseList.at(browsePos)->queryText);
265 showResult();
266 updateBrowseActions();
271 void QueryView::selectAll()
273 part->selectAll();
277 void QueryView::copySelection()
279 kapp->clipboard()->setText(part->selectedText());
283 void QueryView::showFindDialog()
285 KAction *act = part->actionCollection()->action("find");
286 if (act)
287 act->activate();
291 void QueryView::paletteChange ( const QPalette & )
294 optionsChanged();
298 void QueryView::fontChange ( const QFont & )
300 optionsChanged();
304 void QueryView::saveCurrentResultPos()
306 if (!browseList.isEmpty()) {
307 browseList.at(browsePos)->xPos = part->view()->contentsX();
308 browseList.at(browsePos)->yPos = part->view()->contentsY();
313 void QueryView::showResult()
315 if (!isRendering) {
316 isRendering = true;
317 emit(renderingStarted());
320 part->begin();
321 if (browseList.isEmpty()) {
322 part->write(currentHTMLHeader+"<body></body></html>");
323 part->end();
324 } else {
325 BrowseData* brw = browseList.at(browsePos);
326 emit(newCaption(getShortString(brw->queryText.simplifyWhiteSpace(),70)));
327 part->write(currentHTMLHeader+brw->html);
328 part->end();
329 part->view()->setFocus();
334 void QueryView::resultReady(const QString &result, const QString &query)
336 BrowseData* brw = new BrowseData(result,query);
338 if (browseList.isEmpty()) {
339 browsePos = 0;
340 browseList.append(brw);
341 } else {
342 saveCurrentResultPos();
343 while (browseList.count()>browsePos+1)
344 browseList.removeLast();
345 browseList.append(brw);
346 browsePos++;
347 while (browseList.count()>global->maxBrowseListEntrys) {
348 browseList.removeFirst();
349 browsePos--;
353 showResult();
354 emit(enablePrintSave());
355 actQueryCombo->selectAll();
356 updateBrowseActions();
360 void QueryView::partCompleted()
362 if (!browseList.isEmpty())
363 part->view()->setContentsPos(browseList.at(browsePos)->xPos,browseList.at(browsePos)->yPos);
364 if (isRendering) {
365 emit(renderingStopped());
366 isRendering = false;
371 void QueryView::slotURLRequest (const KURL &url, const KParts::URLArgs &)
373 QString type = url.host();
374 QString urlText = url.prettyURL();
375 urlText.remove(0,8+type.length());
377 if (type.length()) { // valid url
378 if(type=="define")
379 emit(defineRequested(urlText));
380 if(type=="dbinfo")
381 interface->showDbInfo(urlText.utf8());
382 if(type=="realhttp")
383 kapp->invokeBrowser("http://"+urlText);
384 if(type=="realftp")
385 kapp->invokeBrowser("ftp://"+urlText);
390 void QueryView::middleButtonClicked()
392 emit(clipboardRequested());
396 // construct the right-mouse-button-popup-menu on demand
397 void QueryView::buildPopupMenu(const QString &url, const QPoint &point)
399 rightBtnMenu->clear();
401 if (!url.isEmpty()) { // menuitem if mouse is over link
402 KURL u(url);
403 QString type = u.host();
404 popupLink = u.prettyURL();
405 popupLink.remove(0,8+type.length());
407 if (type.length()) { // valid url
408 if(type=="define") {
409 rightBtnMenu->insertItem(i18n("Define &Synonym"),
410 this,SLOT(popupDefineLink()));
411 rightBtnMenu->insertItem(i18n("M&atch Synonym"),
412 this,SLOT(popupMatchLink()));
413 rightBtnMenu->insertSeparator();
415 if(type=="dbinfo") {
416 rightBtnMenu->insertItem(i18n("D&atabase Information"),this,SLOT(popupDbInfo()));
417 rightBtnMenu->insertSeparator();
419 if(type=="realhttp") {
420 popupLink.prepend("http://");
421 rightBtnMenu->insertItem(SmallIcon("fileopen"),
422 i18n("&Open Link"),
423 this,SLOT(popupOpenLink()));
424 rightBtnMenu->insertSeparator();
426 if(type=="realftp") {
427 popupLink.prepend("ftp://");
428 rightBtnMenu->insertItem(SmallIcon("fileopen"),
429 i18n("&Open Link"),
430 this,SLOT(popupOpenLink()));
431 rightBtnMenu->insertSeparator();
436 if (part->hasSelection()) {
437 popupSelect = part->selectedText();
438 rightBtnMenu->insertItem(i18n("&Define Selection"),
439 this,SLOT(popupDefineSelect()));
440 rightBtnMenu->insertItem(i18n("&Match Selection"),
441 this,SLOT(popupMatchSelect()));
442 rightBtnMenu->insertSeparator();
443 } else {
444 kapp->clipboard()->setSelectionMode(false);
445 QString text = kapp->clipboard()->text();
446 if (text.isEmpty()) {
447 kapp->clipboard()->setSelectionMode(true);
448 text = kapp->clipboard()->text();
450 if (!text.isEmpty()) {
451 popupSelect = QApplication::clipboard()->text();
452 rightBtnMenu->insertItem(SmallIcon("define_clip"),
453 i18n("&Define Clipboard Content"),
454 this,SLOT(popupDefineSelect()));
455 rightBtnMenu->insertItem(i18n("&Match Clipboard Content"),
456 this,SLOT(popupMatchSelect()));
457 rightBtnMenu->insertSeparator();
461 int ID;
463 if (browseBackPossible()) { // if possible, show string
464 if (browseList.at(browsePos-1)->queryText.isEmpty())
465 rightBtnMenu->insertItem(SmallIcon("back"),
466 i18n("&Back: Information"),
467 this,SLOT(browseBack()));
468 else
469 rightBtnMenu->insertItem(SmallIcon("back"),
470 i18n("&Back: '%1'").arg(getShortString(browseList.at(browsePos-1)->queryText,25)),
471 this,SLOT(browseBack()));
472 } else {
473 ID = rightBtnMenu->insertItem(SmallIcon("back"), i18n("&Back"), this, SLOT(browseBack()));
474 rightBtnMenu->setItemEnabled(ID,false);
477 if (browseForwardPossible()) { // if possible, show string
478 if (browseList.at(browsePos+1)->queryText.isEmpty())
479 rightBtnMenu->insertItem(SmallIcon("forward"),
480 i18n("&Forward: Information"),
481 this,SLOT(browseForward()));
482 else
483 rightBtnMenu->insertItem(SmallIcon("forward"),
484 i18n("&Forward: '%1'").arg(getShortString(browseList.at(browsePos+1)->queryText,25)),
485 this,SLOT(browseForward()));
486 } else {
487 ID = rightBtnMenu->insertItem(SmallIcon("forward"),i18n("&Forward"),this,SLOT(browseForward()));
488 rightBtnMenu->setItemEnabled(ID,false);
491 rightBtnMenu->popup(point);
495 void QueryView::popupDefineLink()
497 emit(defineRequested(popupLink));
501 void QueryView::popupMatchLink()
503 emit(matchRequested(popupLink));
507 void QueryView::popupOpenLink()
509 kapp->invokeBrowser(popupLink);
513 void QueryView::popupDefineSelect()
515 emit(defineRequested(popupSelect));
519 void QueryView::popupMatchSelect()
521 emit(matchRequested(popupSelect));
525 void QueryView::popupDbInfo()
528 interface->showDbInfo(popupLink.utf8());
532 void QueryView::enableAction(const char * name, bool enabled)
534 if (!strcmp(name,"copy"))
535 emit(enableCopy(enabled));
539 void QueryView::browseBack(int index)
541 int x = browsePos-index;
542 if (x>=0) {
543 saveCurrentResultPos();
544 browsePos = x;
545 actQueryCombo->setEditText(browseList.at(browsePos)->queryText);
546 showResult();
547 QTimer::singleShot(0, this, SLOT(updateBrowseActions())); // don't clear the menu in this slot
552 void QueryView::browseForward(int index)
554 int x = browsePos+index;
555 if (x < (int)(browseList.count())) {
556 saveCurrentResultPos();
557 browsePos = x;
558 actQueryCombo->setEditText(browseList.at(browsePos)->queryText);
559 showResult();
560 QTimer::singleShot(0, this, SLOT(updateBrowseActions())); // don't clear the menu in this slot
565 void QueryView::updateBrowseActions()
567 if (browseBackPossible()) {
568 actBack->setEnabled(true);
569 if (browseList.at(browsePos-1)->queryText.isEmpty())
570 actBack->setText(i18n("&Back: Information"));
571 else
572 actBack->setText(i18n("&Back: '%1'").arg(getShortString(browseList.at(browsePos-1)->queryText,25)));
574 actBack->popupMenu()->clear();
575 int i = browsePos-1;
576 int num = 1;
577 QString s;
578 while ((i>=0)&&(num<=10)) {
579 s = browseList.at(i)->queryText;
580 if (s.isEmpty()) s = i18n("Information");
581 actBack->popupMenu()->insertItem(s,num);
582 num++;
583 i--;
585 } else {
586 actBack->setEnabled(false);
587 actBack->setText(i18n("&Back"));
588 actBack->popupMenu()->clear();
591 if (browseForwardPossible()) {
592 actForward->setEnabled(true);
593 if (browseList.at(browsePos+1)->queryText.isEmpty())
594 actForward->setText(i18n("&Forward: Information"));
595 else
596 actForward->setText(i18n("&Forward: '%1'").arg(getShortString(browseList.at(browsePos+1)->queryText,25)));
598 actForward->popupMenu()->clear();
599 int i = browsePos+1;
600 int num = 1;
601 QString s;
602 while ((i<(int)(browseList.count()))&&(num<=10)) {
603 s = browseList.at(i)->queryText;
604 if (s.isEmpty()) s = i18n("Information");
605 actForward->popupMenu()->insertItem(s,num);
606 num++;
607 i++;
609 } else {
610 actForward->setEnabled(false);
611 actForward->setText(i18n("&Forward"));
612 actForward->popupMenu()->clear();
616 //--------------------------------
618 #include "queryview.moc"