Add general Xtraz notification support.
[kdenetwork.git] / kdict / toplevel.cpp
bloba325922ce165a0ba74e7fddb1af3da4e98ea0f70
1 /* -------------------------------------------------------------
3 toplevel.cpp (part of The KDE Dictionary Client)
5 Copyright (C) 2000-2001 Christian Gebauer <gebauer@kde.org>
6 (C) by Matthias Hölzer 1998
8 This file is distributed under the Artistic License.
9 See LICENSE for details.
11 -------------------------------------------------------------
13 TopLevel The toplevel widget of Kdict.
15 ------------------------------------------------------------- */
17 #include <qclipboard.h>
18 //Added by qt3to4:
19 #include <Q3CString>
21 #include <kstandardshortcut.h>
22 #include <kstandardaction.h>
23 #include <kapplication.h>
24 #include <kstatusbar.h>
25 #include <klocale.h>
26 #include <kwin.h>
27 #include <kedittoolbar.h>
28 #include <kdebug.h>
29 #include <dcopclient.h>
31 #include "actions.h"
32 #include "dict.h"
33 #include "options.h"
34 #include "queryview.h"
35 #include "matchview.h"
36 #include "sets.h"
37 #include "toplevel.h"
40 // cut a QString and add "..."
41 QString getShortString(QString str,unsigned int length)
43 if (str.length()>length) {
44 str.truncate(length-3);
45 str.append("...");
47 return str;
51 DictInterface *interface;
52 GlobalData *global;
55 TopLevel::TopLevel(QWidget* parent, const char* name)
56 : DCOPObject("KDictIface"), KMainWindow(parent, name, Qt::WType_TopLevel),
57 optDlg(0L), setsDlg(0L), stopRef(0)
59 kapp->dcopClient()->setDefaultObject(objId());
60 kapp->setMainWidget(this);
62 global = new GlobalData();
63 global->topLevel = this;
64 global->read();
65 interface = new DictInterface();
66 connect(interface,SIGNAL(infoReady()),SLOT(stratDbChanged()));
67 connect(interface,SIGNAL(started(const QString&)),SLOT(clientStarted(const QString&)));
68 connect(interface,SIGNAL(stopped(const QString&)),SLOT(clientStopped(const QString&)));
70 queryView = new QueryView(this);
71 connect(queryView,SIGNAL(defineRequested(const QString&)),SLOT(define(const QString&)));
72 connect(queryView,SIGNAL(matchRequested(const QString&)),SLOT(match(const QString&)));
73 connect(queryView,SIGNAL(clipboardRequested()),SLOT(defineClipboard()));
74 connect(queryView,SIGNAL(enableCopy(bool)),SLOT(enableCopy(bool)));
75 connect(queryView,SIGNAL(enablePrintSave()),SLOT(enablePrintSave()));
76 connect(queryView,SIGNAL(renderingStarted()),SLOT(renderingStarted()));
77 connect(queryView,SIGNAL(renderingStopped()),SLOT(renderingStopped()));
78 connect(queryView,SIGNAL(newCaption(const QString&)),SLOT(newCaption(const QString&)));
80 matchView = new MatchView();
81 connect(matchView,SIGNAL(defineRequested(const QString&)),SLOT(define(const QString&)));
82 connect(matchView,SIGNAL(matchRequested(const QString&)),SLOT(match(const QString&)));
83 connect(matchView,SIGNAL(clipboardRequested()),SLOT(matchClipboard()));
84 connect(matchView,SIGNAL(windowClosed()),SLOT(toggleMatchListShow()));
85 connect(&resetStatusbarTimer,SIGNAL(timeout()),SLOT(resetStatusbar()));
87 setupStatusBar();
88 setupActions();
89 recreateGUI();
90 buildHistMenu();
92 if (global->showMatchList)
93 { // show splitter, html view & match list
94 splitter = new QSplitter(Qt::Horizontal,this);
95 splitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
96 queryView->reparent(splitter,0,queryView->pos(),true);
97 matchView->reparent(splitter,0,matchView->pos(),true);
98 setCentralWidget(splitter);
99 splitter->setResizeMode(matchView,QSplitter::KeepSize);
100 adjustMatchViewSize();
102 else
103 { // show only html view
104 setCentralWidget(queryView);
105 matchView->hide();
108 //apply settings
109 resize(600,390);
110 applyMainWindowSettings(KGlobal::config(),"toplevel_options");
111 stratDbChanged(); // fill combos, build menus
113 actQueryCombo->setFocus(); // place cursor in combobox
117 TopLevel::~TopLevel()
122 void TopLevel::normalStartup()
124 if (global->defineClipboard)
125 defineClipboard();
128 // ******* DCOP Interface ********************************************************
130 void TopLevel::quit()
132 kDebug(5004) << "*DCOP call* TopLevel::quit()" << endl;
133 kapp->closeAllWindows();
137 void TopLevel::makeActiveWindow()
139 kDebug(5004) << "*DCOP call* TopLevel::makeActiveWindow()" << endl;
140 raiseWindow();
144 void TopLevel::definePhrase(QString phrase)
146 kDebug(5004) << "*DCOP call* TopLevel::definePhrase()" << endl;
147 define(phrase);
148 raiseWindow();
152 void TopLevel::matchPhrase(QString phrase)
154 kDebug(5004) << "*DCOP call* TopLevel::matchPhrase()" << endl;
155 match(phrase);
156 raiseWindow();
160 void TopLevel::defineClipboardContent()
162 kDebug(5004) << "*DCOP call* TopLevel::defineClipboardContent()" << endl;
163 defineClipboard();
164 raiseWindow();
168 void TopLevel::matchClipboardContent()
170 kDebug(5004) << "*DCOP call* TopLevel::matchClipboardContent()" << endl;
171 matchClipboard();
172 raiseWindow();
176 QStringList TopLevel::getDatabases()
178 kDebug(5004) << "*DCOP call* TopLevel::getDatabases()" << endl;
179 return global->databases;
183 QString TopLevel::currentDatabase()
185 kDebug(5004) << "*DCOP call* TopLevel::currentDatabase()" << endl;
186 return global->databases[global->currentDatabase];
190 QStringList TopLevel::getStrategies()
192 kDebug(5004) << "*DCOP call* TopLevel::getStrategies()" << endl;
193 return global->strategies;
197 QString TopLevel::currentStrategy()
199 kDebug(5004) << "*DCOP call* TopLevel::currentStrategy()" << endl;
200 return global->strategies[global->currentStrategy];
204 bool TopLevel::setDatabase(QString db)
206 kDebug(5004) << "*DCOP call* TopLevel::setDatabase()" << endl;
208 int newCurrent = global->databases.findIndex(db);
209 if (newCurrent == -1)
210 return false;
211 else {
212 global->currentDatabase = newCurrent;
213 actDbCombo->setCurrentItem(global->currentDatabase);
214 return true;
219 bool TopLevel::setStrategy(QString strategy)
221 kDebug(5004) << "*DCOP call* TopLevel::setStrategy()" << endl;
223 return matchView->selectStrategy(strategy);
227 bool TopLevel::historyGoBack()
229 kDebug(5004) << "*DCOP call* TopLevel::historyGoBack()" << endl;
231 if (!queryView->browseBackPossible())
232 return false;
233 else {
234 queryView->browseBack();
235 return true;
240 bool TopLevel::historyGoForward()
242 kDebug(5004) << "*DCOP call* TopLevel::historyGoForward()" << endl;
244 if (!queryView->browseForwardPossible())
245 return false;
246 else {
247 queryView->browseForward();
248 return true;
252 // *******************************************************************************
254 void TopLevel::define(const QString &query)
256 kDebug(5004) << "TopLevel::define()" << endl;
257 actQueryCombo->setEditText(query);
258 doDefine();
262 void TopLevel::defineClipboard()
264 kDebug(5004) << "TopLevel::defineClipboard()" << endl;
265 QString text = kapp->clipboard()->text(QClipboard::Selection);
266 if (text.isEmpty()) {
267 text = kapp->clipboard()->text(QClipboard::Clipboard);
269 define(text);
273 void TopLevel::match(const QString &query)
275 kDebug(5004) << "TopLevel::match()" << endl;
276 actQueryCombo->setEditText(query);
277 doMatch();
281 void TopLevel::matchClipboard()
283 kDebug(5004) << "TopLevel::matchClipboard()" << endl;
284 QString text = kapp->clipboard()->text(QClipboard::Selection);
285 if (text.isEmpty()) {
286 text = kapp->clipboard()->text(QClipboard::Clipboard);
288 match(text);
292 bool TopLevel::queryClose()
294 kDebug(5004) << "TopLevel::queryClose()" << endl;
296 saveMainWindowSettings(KGlobal::config(),"toplevel_options");
297 saveMatchViewSize();
298 global->queryComboCompletionMode = actQueryCombo->completionMode();
300 global->write();
302 return true;
306 void TopLevel::setupActions()
308 // file menu...
309 actSave = KStandardAction::save(queryView, SLOT(saveQuery()), actionCollection());
310 actSave->setText(i18n("&Save As..."));
311 actSave->setEnabled(false);
312 actPrint = KStandardAction::print(queryView, SLOT(printQuery()), actionCollection());
313 actPrint->setEnabled(false);
314 actStartQuery = new KAction(i18n("St&art Query"),"reload", 0 , this,
315 SLOT(doDefine()), actionCollection(), "start_query");
316 actStopQuery = new KAction(i18n("St&op Query"),"stop", 0 , this,
317 SLOT(stopClients()), actionCollection(), "stop_query");
318 actStopQuery->setEnabled(false);
319 KStandardAction::quit(kapp, SLOT(closeAllWindows()), actionCollection());
321 // edit menu...
322 actCopy = KStandardAction::copy(queryView, SLOT(copySelection()), actionCollection());
323 actCopy->setEnabled(false);
324 KStandardAction::selectAll(queryView, SLOT(selectAll()), actionCollection());
325 new KAction(i18n("&Define Clipboard Content"), "define_clip", 0 , this,
326 SLOT(defineClipboard()), actionCollection(), "define_clipboard");
327 new KAction(i18n("&Match Clipboard Content"), 0 , this,
328 SLOT(matchClipboard()), actionCollection(), "match_clipboard");
329 KStandardAction::find(queryView, SLOT(showFindDialog()), actionCollection());
331 // history menu...
332 actBack = new KToolBarPopupAction(i18n("&Back"), "back", KStandardShortcut::shortcut(KStandardShortcut::Back),
333 queryView, SLOT(browseBack()), actionCollection(),"browse_back");
334 actBack->setDelayed(true);
335 actBack->setStickyMenu(false);
336 actBack->setEnabled(false);
337 actForward = new KToolBarPopupAction(i18n("&Forward"), "forward", KStandardShortcut::shortcut(KStandardShortcut::Forward),
338 queryView, SLOT(browseForward()), actionCollection(),"browse_forward");
339 actForward->setDelayed(true);
340 actForward->setStickyMenu(false);
341 actForward->setEnabled(false);
342 new KAction(i18n("&Clear History"), 0 , this,
343 SLOT(clearQueryHistory()), actionCollection(), "clear_history");
345 // server menu...
346 new KAction(i18n("&Get Capabilities"), 0 , interface,
347 SLOT(updateServer()), actionCollection(), "get_capabilities");
348 new KAction(i18n("Edit &Database Sets..."), "edit", 0 , this,
349 SLOT(showSetsDialog()), actionCollection(), "edit_sets");
350 new KAction(i18n("&Summary"), 0 , interface,
351 SLOT(showDatabases()), actionCollection(), "db_summary");
352 new KAction(i18n("S&trategy Information"), 0 , interface,
353 SLOT(showStrategies()), actionCollection(), "strategy_info");
354 new KAction(i18n("&Server Information"), 0 , interface,
355 SLOT(showInfo()), actionCollection(), "server_info");
357 // settings menu...
358 createStandardStatusBarAction();
359 setStandardToolBarMenuEnabled(true);
361 actShowMatchList = new KToggleAction(i18n("Show &Match List"), 0 , this,
362 SLOT(toggleMatchListShow()), actionCollection(), "show_match");
363 actShowMatchList->setCheckedState(i18n("Hide &Match List"));
364 actShowMatchList->setChecked(global->showMatchList);
365 KStandardAction::keyBindings(guiFactory(), SLOT(configureShortcuts()),
366 actionCollection());
367 KStandardAction::configureToolbars(this, SLOT(slotConfToolbar()), actionCollection());
368 KStandardAction::preferences(this, SLOT(showOptionsDialog()), actionCollection());
370 // toolbar...
371 new KAction(i18n("Clear Input Field"), "query_erase", 0 , this,
372 SLOT(clearInput()), actionCollection(), "clear_query");
374 actQueryLabel = new DictLabelAction(i18n("&Look for:"), actionCollection(), "look_label");
375 actQueryCombo = new DictComboAction(i18n("Query"), actionCollection(), "query_combo",true,true);
376 connect(actQueryCombo,SIGNAL(activated(const QString &)), SLOT(define(const QString&)));
377 actQueryCombo->setCompletionMode(global->queryComboCompletionMode);
378 actDbLabel = new DictLabelAction(i18n("&in"), actionCollection(), "in_label");
379 actDbCombo = new DictComboAction(i18n("Databases"), actionCollection(), "db_combo",false,false);
380 connect(actDbCombo,SIGNAL(activated(int)),SLOT(databaseSelected(int)));
381 actDefineBtn = new DictButtonAction(i18n("&Define"), this, SLOT(doDefine()), actionCollection(), "define_btn");
382 actMatchBtn = new DictButtonAction(i18n("&Match"), this, SLOT(doMatch()), actionCollection(), "match_btn");
384 queryView->setActions(actBack,actForward,actQueryCombo);
388 void TopLevel::setupStatusBar()
390 statusBar()->insertItem(i18n(" Ready "),0,2);
391 statusBar()->setItemAlignment(0,Qt::AlignLeft | Qt::AlignVCenter);
393 QString serverInfo;
394 if (global->authEnabled)
395 serverInfo = QString(" %1@%2:%3 ").arg(getShortString(global->user,50))
396 .arg(getShortString(global->server,50))
397 .arg(global->port);
398 else
399 serverInfo = QString(" %1:%3 ").arg(getShortString(global->server,50))
400 .arg(global->port);
401 statusBar()->insertItem(serverInfo, 1,3);
402 statusBar()->setItemAlignment(1,Qt::AlignLeft | Qt::AlignVCenter);
406 void TopLevel::recreateGUI()
408 kDebug(5004) << "TopLevel::recreateGUI()" << endl;
409 createGUI("kdictui.rc", false);
410 actQueryCombo->setList(global->queryHistory);
411 actQueryCombo->clearEdit();
412 actQueryLabel->setBuddy(actQueryCombo->widget());
414 actDbCombo->setList(global->databases);
415 actDbCombo->setCurrentItem(global->currentDatabase);
416 actDbLabel->setBuddy(actDbCombo->widget());
417 int bwidth;
418 if (actDefineBtn->widthHint() > actMatchBtn->widthHint())
419 bwidth = actDefineBtn->widthHint();
420 else
421 bwidth = actMatchBtn->widthHint();
422 actDefineBtn->setWidth(bwidth);
423 actMatchBtn->setWidth(bwidth);
427 // add text in the query-combobox to the history
428 void TopLevel::addCurrentInputToHistory()
430 QString text(actQueryCombo->currentText());
432 // maintain queryHistory
433 global->queryHistory.remove(text); // no double entries
434 global->queryHistory.prepend(text); // prepend new item
435 while (global->queryHistory.count()>global->maxHistEntrys) // shorten list
436 global->queryHistory.remove(global->queryHistory.fromLast());
438 actQueryCombo->setList(global->queryHistory);
439 actQueryCombo->setCurrentItem(0);
440 buildHistMenu();
445 // erase text in query-combobox
446 void TopLevel::clearInput()
448 actQueryCombo->clearEdit();
449 actQueryCombo->setFocus(); // place cursor in combobox
453 // define text in the combobox
454 void TopLevel::doDefine()
456 QString text(actQueryCombo->currentText());
458 if (!text.isEmpty())
460 addCurrentInputToHistory();
461 actQueryCombo->selectAll();
462 interface->define(text);
467 void TopLevel::doMatch()
469 QString text(actQueryCombo->currentText());
471 if (!text.isEmpty())
473 addCurrentInputToHistory();
474 actQueryCombo->selectAll();
476 if (!global->showMatchList)
478 toggleMatchListShow();
481 matchView->match(text);
482 setCaption(getShortString(text.simplified(),70));
487 void TopLevel::stopClients()
489 interface->stop();
490 queryView->stop();
494 // rebuild history menu on demand
495 void TopLevel::buildHistMenu()
497 unplugActionList("history_items");
499 historyActionList.setAutoDelete(true);
500 historyActionList.clear();
502 unsigned int i = 0;
503 while ((i<10)&&(i<global->queryHistory.count())) {
504 historyActionList.append( new KAction(getShortString(global->queryHistory[i],70), 0, this, SLOT(queryHistMenu()),
505 (QObject*)0, global->queryHistory[i].utf8().data()) );
506 i++;
509 plugActionList("history_items", historyActionList);
513 // process a query via the history menu
514 void TopLevel::queryHistMenu()
516 Q3CString name = sender()->name();
517 if (!name.isEmpty())
518 define(QString::fromUtf8(name));
522 void TopLevel::clearQueryHistory()
524 global->queryHistory.clear();
525 actQueryCombo->clear();
526 buildHistMenu();
530 // fill combos, rebuild menus
531 void TopLevel::stratDbChanged()
533 actDbCombo->setList(global->databases);
534 actDbCombo->setCurrentItem(global->currentDatabase);
535 matchView->updateStrategyCombo();
537 unplugActionList("db_detail");
539 dbActionList.setAutoDelete(true);
540 dbActionList.clear();
542 for (unsigned int i=0;i<global->serverDatabases.count();i++)
543 dbActionList.append( new KAction(global->serverDatabases[i], 0, this, SLOT(dbInfoMenuClicked()),
544 (QObject*)0, global->serverDatabases[i].utf8().data()) );
546 plugActionList("db_detail", dbActionList);
550 void TopLevel::dbInfoMenuClicked()
552 Q3CString name = sender()->name();
553 if (!name.isEmpty())
554 interface->showDbInfo(name);
558 void TopLevel::databaseSelected(int num)
560 global->currentDatabase = num;
564 void TopLevel::enableCopy(bool selected)
566 actCopy->setEnabled(selected);
570 void TopLevel::enablePrintSave()
572 actSave->setEnabled(true);
573 actPrint->setEnabled(true);
577 void TopLevel::clientStarted(const QString &message)
579 statusBar()->changeItem(message,0);
580 resetStatusbarTimer.stop();
581 stopRef++;
582 actStopQuery->setEnabled(stopRef>0); // enable stop-icon
583 kapp->setOverrideCursor(Qt::WaitCursor);
587 void TopLevel::clientStopped(const QString &message)
589 statusBar()->changeItem(message,0);
590 resetStatusbarTimer.start(4000);
591 if (stopRef > 0)
592 stopRef--;
593 actStopQuery->setEnabled(stopRef>0); // disable stop-icon
594 kapp->restoreOverrideCursor();
598 void TopLevel::resetStatusbar()
600 resetStatusbarTimer.stop();
601 statusBar()->changeItem(i18n(" Ready "),0);
605 void TopLevel::renderingStarted()
607 stopRef++;
608 actStopQuery->setEnabled(stopRef>0); // disable stop-icon
609 kapp->setOverrideCursor(Qt::WaitCursor);
613 void TopLevel::renderingStopped()
615 if (stopRef > 0)
616 stopRef--;
617 actStopQuery->setEnabled(stopRef>0); // disable stop-icon
618 kapp->restoreOverrideCursor();
622 void TopLevel::newCaption(const QString &s)
624 setCaption(s);
627 void TopLevel::toggleMatchListShow()
629 saveMatchViewSize();
630 if (global->showMatchList) // list is visible -> hide it
632 global->showMatchList = false;
633 queryView->reparent(this,0,queryView->pos(),true);
634 matchView->reparent(this,0,matchView->pos(),true);
635 matchView->hide();
636 delete splitter;
637 setCentralWidget(queryView);
639 else // list is not visible -> show it
641 global->showMatchList = true;
642 splitter = new QSplitter(Qt::Horizontal,this);
643 splitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
644 setCentralWidget(splitter);
645 splitter->show();
646 queryView->reparent(splitter,0,queryView->pos(),true);
647 matchView->reparent(splitter,0,matchView->pos(),true);
648 splitter->setResizeMode(matchView,QSplitter::KeepSize);
649 adjustMatchViewSize();
652 actShowMatchList->setChecked(global->showMatchList);
656 void TopLevel::saveMatchViewSize()
658 if (global->showMatchList)
660 global->splitterSizes = splitter->sizes();
665 void TopLevel::adjustMatchViewSize()
667 if (global->splitterSizes.count()==2)
669 splitter->setSizes(global->splitterSizes);
674 void TopLevel::slotConfToolbar()
676 saveMainWindowSettings(KGlobal::config(),"toplevel_options");
677 KEditToolbar dlg(actionCollection(), "kdictui.rc");
678 connect(&dlg,SIGNAL( newToolbarConfig() ), this, SLOT( slotNewToolbarConfig() ));
679 dlg.exec();
683 void TopLevel::slotNewToolbarConfig()
685 recreateGUI();
686 applyMainWindowSettings(KGlobal::config(),"toplevel_options");
687 buildHistMenu(); // actionlists must be inserted
688 stratDbChanged();
692 void TopLevel::showSetsDialog()
694 if (!setsDlg) {
695 setsDlg = new DbSetsDialog(this);
696 connect(setsDlg,SIGNAL(setsChanged()),this,SLOT(setsChanged()));
697 connect(setsDlg,SIGNAL(dialogClosed()),this,SLOT(hideSetsDialog()));
698 setsDlg->show();
699 } else {
700 KWin::activateWindow(setsDlg->winId());
705 void TopLevel::hideSetsDialog()
707 if (setsDlg) {
708 setsDlg->delayedDestruct();
709 setsDlg = 0L;
714 void TopLevel::setsChanged()
716 actDbCombo->setList(global->databases);
717 actDbCombo->setCurrentItem(global->currentDatabase);
721 void TopLevel::showOptionsDialog()
723 if (!optDlg) {
724 optDlg = new OptionsDialog(this);
725 connect(optDlg,SIGNAL(optionsChanged()),this,SLOT(optionsChanged()));
726 connect(optDlg,SIGNAL(finished()),this,SLOT(hideOptionsDialog()));
727 optDlg->show();
728 } else {
729 KWin::activateWindow(optDlg->winId());
734 void TopLevel::hideOptionsDialog()
736 if (optDlg) {
737 optDlg->delayedDestruct();
738 optDlg=0;
743 void TopLevel::optionsChanged()
745 QString serverInfo;
746 if (global->authEnabled)
747 serverInfo = QString(" %1@%2:%3 ").arg(getShortString(global->user,50))
748 .arg(getShortString(global->server,50))
749 .arg(global->port);
750 else
751 serverInfo = QString(" %1:%3 ").arg(getShortString(global->server,50))
752 .arg(global->port);
753 statusBar()->changeItem(serverInfo,1);
754 interface->serverChanged(); // inform client
755 queryView->optionsChanged(); // inform html-view
758 void TopLevel::raiseWindow()
760 // Bypass focus stealing prevention
761 kapp->updateUserTimestamp();
763 KWin::WindowInfo info = KWin::windowInfo( winId() );
765 if ( !info.isOnCurrentDesktop() )
767 KWin::setOnDesktop( winId(), KWin::currentDesktop() );
770 KWin::activateWindow(winId());
774 //--------------------------------
776 #include "toplevel.moc"