1 /***************************************************************************
2 * Copyright (C) 2003 by Sébastien Laoût *
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. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
23 #include <qwidgetstack.h>
29 #include <qwhatsthis.h>
30 #include <kpopupmenu.h>
31 #include <qsignalmapper.h>
33 #include <kicontheme.h>
34 #include <kiconloader.h>
36 #include <kstringhandler.h>
37 #include <kmessagebox.h>
38 #include <kfiledialog.h>
39 #include <kprogress.h>
40 #include <kstandarddirs.h>
41 #include <kaboutdata.h>
44 #include <kpassivepopup.h>
45 #include <kxmlguifactory.h>
46 #include <kcmdlineargs.h>
47 #include <kglobalaccel.h>
48 #include <kapplication.h>
49 #include <kkeydialog.h>
50 #include <dcopclient.h>
57 #include "debugwindow.h"
59 #include "basketfactory.h"
60 #include "softwareimporters.h"
61 #include "colorpicker.h"
62 #include "regiongrabber.h"
63 #include "basketlistview.h"
64 #include "basketproperties.h"
66 #include "newbasketdialog.h"
68 #include "formatimporter.h"
69 #include "basketstatusbar.h"
70 #include "backgroundmanager.h"
71 #include "noteedit.h" // To launch InlineEditors::initToolBars()
73 #include "htmlexporter.h"
74 #include "crashhandler.h"
77 #include "notefactory.h"
78 #include "notecontent.h"
82 const int BNPView::c_delayTooltipTime
= 275;
84 BNPView::BNPView(QWidget
*parent
, const char *name
, KXMLGUIClient
*aGUIClient
,
85 KActionCollection
*actionCollection
, BasketStatusBar
*bar
)
86 : DCOPObject("BasketIface"), QSplitter(Qt::Horizontal
, parent
, name
), m_actLockBasket(0), m_actPassBasket(0),
87 m_loading(true), m_newBasketPopup(false), m_firstShow(true),
88 m_regionGrabber(0), m_passiveDroppedSelection(0), m_passivePopup(0), m_actionCollection(actionCollection
),
89 m_guiClient(aGUIClient
), m_statusbar(bar
), m_tryHideTimer(0), m_hideTimer(0)
92 Settings::loadConfig();
94 Global::bnpView
= this;
96 // Needed when loading the baskets:
97 Global::globalAccel
= new KGlobalAccel(this); // FIXME: might be null (KPart case)!
98 Global::backgroundManager
= new BackgroundManager();
100 setupGlobalShortcuts();
102 QTimer::singleShot(0, this, SLOT(lateInit()));
107 int treeWidth
= Global::bnpView
->sizes()[Settings::treeOnLeft() ? 0 : 1];
109 Settings::setBasketTreeWidth(treeWidth
);
111 if (currentBasket() && currentBasket()->isDuringEdit())
112 currentBasket()->closeEditor();
114 Settings::saveConfig();
118 delete Global::systemTray
;
119 Global::systemTray
= 0;
120 delete m_colorPicker
;
123 NoteDrag::createAndEmptyCuttingTmpFolder(); // Clean the temporary folder we used
126 void BNPView::lateInit()
129 InlineEditors* instance = InlineEditors::instance();
133 KToolBar* toolbar = instance->richTextToolBar();
141 if (Settings::useSystray() && KCmdLineArgs::parsedArgs() && KCmdLineArgs::parsedArgs()->isSet("start-hidden"))
142 if(Global::mainWindow()) Global::mainWindow()->hide();
143 else if (Settings::useSystray() && kapp
->isRestored())
144 if(Global::mainWindow()) Global::mainWindow()->setShown(!Settings::startDocked());
149 // If the main window is hidden when session is saved, Container::queryClose()
150 // isn't called and the last value would be kept
151 Settings::setStartDocked(true);
152 Settings::saveConfig();
154 /* System tray icon */
155 Global::systemTray
= new SystemTray(Global::mainWindow());
156 connect( Global::systemTray
, SIGNAL(showPart()), this, SIGNAL(showPart()) );
157 if (Settings::useSystray())
158 Global::systemTray
->show();
161 DEBUG_WIN
<< "Baskets are loaded from " + Global::basketsFolder();
163 NoteDrag::createAndEmptyCuttingTmpFolder(); // If last exec hasn't done it: clean the temporary folder we will use
164 Tag::loadTags(); // Tags should be ready before loading baskets, but tags need the mainContainer to be ready to create KActions!
167 // If no basket has been found, try to import from an older version,
168 if (!firstListViewItem()) {
170 dir
.mkdir(Global::basketsFolder());
171 if (FormatImporter::shouldImportBaskets()) {
172 FormatImporter::importBaskets();
175 if (!firstListViewItem()) {
176 // Create first basket:
177 BasketFactory::newBasket(/*icon=*/"", /*name=*/i18n("General"), /*backgroundImage=*/"", /*backgroundColor=*/QColor(), /*textColor=*/QColor(), /*templateName=*/"1column", /*createIn=*/0);
181 // Load the Welcome Baskets if it is the First Time:
182 if (!Settings::welcomeBasketsAdded()) {
184 Settings::setWelcomeBasketsAdded(true);
185 Settings::saveConfig();
188 m_tryHideTimer
= new QTimer(this);
189 m_hideTimer
= new QTimer(this);
190 connect( m_tryHideTimer
, SIGNAL(timeout()), this, SLOT(timeoutTryHide()) );
191 connect( m_hideTimer
, SIGNAL(timeout()), this, SLOT(timeoutHide()) );
193 // Preload every baskets for instant filtering:
194 /*StopWatch::start(100);
195 QListViewItemIterator it(m_tree);
196 while (it.current()) {
197 BasketListViewItem *item = ((BasketListViewItem*)it.current());
198 item->basket()->load();
199 kapp->processEvents();
202 StopWatch::check(100);*/
205 void BNPView::addWelcomeBaskets()
207 // Possible paths where to find the welcome basket archive, trying the translated one, and falling back to the English one:
208 QStringList possiblePaths
;
209 if (QString(KGlobal::locale()->encoding()) == QString("UTF-8")) { // Welcome baskets are encoded in UTF-8. If the system is not, then use the English version:
210 possiblePaths
.append(KGlobal::dirs()->findResource("data", "basket/welcome/Welcome_" + KGlobal::locale()->language() + ".baskets"));
211 possiblePaths
.append(KGlobal::dirs()->findResource("data", "basket/welcome/Welcome_" + QStringList::split("_", KGlobal::locale()->language())[0] + ".baskets"));
213 possiblePaths
.append(KGlobal::dirs()->findResource("data", "basket/welcome/Welcome_en_US.baskets"));
215 // Take the first EXISTING basket archive found:
218 for (QStringList::Iterator it
= possiblePaths
.begin(); it
!= possiblePaths
.end(); ++it
) {
219 if (dir
.exists(*it
)) {
230 void BNPView::onFirstShow()
232 // Don't enable LikeBack until bnpview is shown. This way it works better with kontact.
234 /* Global::likeBack = new LikeBack(LikeBack::AllButtons, / *showBarByDefault=* /true, Global::config(), Global::about());
235 Global::likeBack->setServer("basket.linux62.org", "/likeback/send.php");
236 Global:likeBack->setAcceptedLanguages(QStringList::split(";", "en;fr"), i18n("Only english and french languages are accepted."));
238 Global::likeBack->disableBar(); // See BNPView::shown() and BNPView::hide().
242 Global::likeBack
->disableBar(); // See BNPView::shown() and BNPView::hide().
245 LikeBack::init(Global::config(), Global::about(), LikeBack::AllButtons);
246 LikeBack::setServer("basket.linux62.org", "/likeback/send.php");
247 // LikeBack::setServer("localhost", "/~seb/basket/likeback/send.php");
248 LikeBack::setCustomLanguageMessage(i18n("Only english and french languages are accepted."));
249 // LikeBack::setWindowNamesListing(LikeBack:: / *NoListing* / / *WarnUnnamedWindows* / AllWindows);
252 // In late init, because we need kapp->mainWidget() to be set!
256 m_statusbar
->setupStatusBar();
258 int treeWidth
= Settings::basketTreeWidth();
260 treeWidth
= m_tree
->fontMetrics().maxWidth() * 11;
261 QValueList
<int> splitterSizes
;
262 splitterSizes
.append(treeWidth
);
263 setSizes(splitterSizes
);
266 void BNPView::setupGlobalShortcuts()
268 /* Global shortcuts */
269 KGlobalAccel
*globalAccel
= Global::globalAccel
; // Better for the following lines
271 // Ctrl+Shift+W only works when started standalone:
272 QWidget
*basketMainWindow
= (QWidget
*) (Global::bnpView
->parent()->inherits("MainWindow") ? Global::bnpView
->parent() : 0);
274 if (basketMainWindow
) {
275 globalAccel
->insert( "global_show_hide_main_window", i18n("Show/hide main window"),
276 i18n("Allows you to show main Window if it is hidden, and to hide it if it is shown."),
277 Qt::CTRL
+ Qt::ALT
+ Qt::SHIFT
+ Qt::Key_W
, Qt::CTRL
+ Qt::ALT
+ Qt::SHIFT
+ Qt::Key_W
,
278 basketMainWindow
, SLOT(changeActive()), true, true );
280 globalAccel
->insert( "global_paste", i18n("Paste clipboard contents in current basket"),
281 i18n("Allows you to paste clipboard contents in the current basket without having to open the main window."),
282 Qt::CTRL
+ Qt::ALT
+ Qt::SHIFT
+ Qt::Key_V
, Qt::CTRL
+ Qt::ALT
+ Qt::SHIFT
+ Qt::Key_V
,
283 Global::bnpView
, SLOT(globalPasteInCurrentBasket()), true, true );
284 globalAccel
->insert( "global_show_current_basket", i18n("Show current basket name"),
285 i18n("Allows you to know basket is current without opening the main window."),
287 Global::bnpView
, SLOT(showPassiveContentForced()), true, true );
288 globalAccel
->insert( "global_paste_selection", i18n("Paste selection in current basket"),
289 i18n("Allows you to paste clipboard selection in the current basket without having to open the main window."),
290 Qt::CTRL
+ Qt::ALT
+ Qt::SHIFT
+ Qt::Key_S
, Qt::CTRL
+ Qt::ALT
+ Qt::SHIFT
+ Qt::Key_S
,
291 Global::bnpView
, SLOT(pasteSelInCurrentBasket()), true, true );
292 globalAccel
->insert( "global_new_basket", i18n("Create a new basket"),
293 i18n("Allows you to create a new basket without having to open the main window (you then can use the other global shortcuts to add a note, paste clipboard or paste selection in this new basket)."),
295 Global::bnpView
, SLOT(askNewBasket()), true, true );
296 globalAccel
->insert( "global_previous_basket", i18n("Go to previous basket"),
297 i18n("Allows you to change current basket to the previous one without having to open the main window."),
299 Global::bnpView
, SLOT(goToPreviousBasket()), true, true );
300 globalAccel
->insert( "global_next_basket", i18n("Go to next basket"),
301 i18n("Allows you to change current basket to the next one without having to open the main window."),
303 Global::bnpView
, SLOT(goToNextBasket()), true, true );
304 // globalAccel->insert( "global_note_add_text", i18n("Insert plain text note"),
305 // i18n("Add a plain text note to the current basket without having to open the main window."),
306 // "", "", //Qt::CTRL+Qt::ALT+Qt::Key_T, Qt::CTRL+Qt::ALT+Qt::Key_T,
307 // Global::bnpView, SLOT(addNoteText()), true, true );
308 globalAccel
->insert( "global_note_add_html", i18n("Insert text note"),
309 i18n("Add a text note to the current basket without having to open the main window."),
310 Qt::CTRL
+ Qt::ALT
+ Qt::SHIFT
+ Qt::Key_T
, Qt::CTRL
+ Qt::ALT
+ Qt::SHIFT
+ Qt::Key_T
, //"", "",
311 Global::bnpView
, SLOT(addNoteHtml()), true, true );
312 globalAccel
->insert( "global_note_add_image", i18n("Insert image note"),
313 i18n("Add an image note to the current basket without having to open the main window."),
315 Global::bnpView
, SLOT(addNoteImage()), true, true );
316 globalAccel
->insert( "global_note_add_link", i18n("Insert link note"),
317 i18n("Add a link note to the current basket without having to open the main window."),
319 Global::bnpView
, SLOT(addNoteLink()), true, true );
320 globalAccel
->insert( "global_note_add_color", i18n("Insert color note"),
321 i18n("Add a color note to the current basket without having to open the main window."),
323 Global::bnpView
, SLOT(addNoteColor()), true, true );
324 globalAccel
->insert( "global_note_pick_color", i18n("Pick color from screen"),
325 i18n("Add a color note picked from one pixel on screen to the current basket without "
326 "having to open the main window."),
328 Global::bnpView
, SLOT(slotColorFromScreenGlobal()), true, true );
329 globalAccel
->insert( "global_note_grab_screenshot", i18n("Grab screen zone"),
330 i18n("Grab a screen zone as an image in the current basket without "
331 "having to open the main window."),
333 Global::bnpView
, SLOT(grabScreenshotGlobal()), true, true );
334 globalAccel
->readSettings();
335 globalAccel
->updateConnections();
338 void BNPView::initialize()
340 /// Configure the List View Columns:
341 m_tree
= new BasketTreeListView(this);
342 m_tree
->addColumn(i18n("Baskets"));
343 m_tree
->setColumnWidthMode(0, QListView::Maximum
);
344 m_tree
->setFullWidth(true);
345 m_tree
->setSorting(-1/*Disabled*/);
346 m_tree
->setRootIsDecorated(true);
347 m_tree
->setTreeStepSize(16);
348 m_tree
->setLineWidth(1);
349 m_tree
->setMidLineWidth(0);
350 m_tree
->setFocusPolicy(QWidget::NoFocus
);
352 /// Configure the List View Drag and Drop:
353 m_tree
->setDragEnabled(true);
354 m_tree
->setAcceptDrops(true);
355 m_tree
->setItemsMovable(true);
356 m_tree
->setDragAutoScroll(true);
357 m_tree
->setDropVisualizer(true);
358 m_tree
->setDropHighlighter(true);
360 /// Configure the Splitter:
361 m_stack
= new QWidgetStack(this);
363 setOpaqueResize(true);
365 setCollapsible(m_tree
, true);
366 setCollapsible(m_stack
, false);
367 setResizeMode(m_tree
, QSplitter::KeepSize
);
368 setResizeMode(m_stack
, QSplitter::Stretch
);
370 /// Configure the List View Signals:
371 connect( m_tree
, SIGNAL(returnPressed(QListViewItem
*)), this, SLOT(slotPressed(QListViewItem
*)) );
372 connect( m_tree
, SIGNAL(selectionChanged(QListViewItem
*)), this, SLOT(slotPressed(QListViewItem
*)) );
373 connect( m_tree
, SIGNAL(pressed(QListViewItem
*)), this, SLOT(slotPressed(QListViewItem
*)) );
374 connect( m_tree
, SIGNAL(expanded(QListViewItem
*)), this, SLOT(needSave(QListViewItem
*)) );
375 connect( m_tree
, SIGNAL(collapsed(QListViewItem
*)), this, SLOT(needSave(QListViewItem
*)) );
376 connect( m_tree
, SIGNAL(contextMenu(KListView
*, QListViewItem
*, const QPoint
&)), this, SLOT(slotContextMenu(KListView
*, QListViewItem
*, const QPoint
&)) );
377 connect( m_tree
, SIGNAL(mouseButtonPressed(int, QListViewItem
*, const QPoint
&, int)), this, SLOT(slotMouseButtonPressed(int, QListViewItem
*, const QPoint
&, int)) );
378 connect( m_tree
, SIGNAL(doubleClicked(QListViewItem
*, const QPoint
&, int)), this, SLOT(slotShowProperties(QListViewItem
*, const QPoint
&, int)) );
380 connect( m_tree
, SIGNAL(expanded(QListViewItem
*)), this, SIGNAL(basketChanged()) );
381 connect( m_tree
, SIGNAL(collapsed(QListViewItem
*)), this, SIGNAL(basketChanged()) );
382 connect( this, SIGNAL(basketNumberChanged(int)), this, SIGNAL(basketChanged()) );
384 connect( this, SIGNAL(basketNumberChanged(int)), this, SLOT(slotBasketNumberChanged(int)) );
385 connect( this, SIGNAL(basketChanged()), this, SLOT(slotBasketChanged()) );
388 Global::likeBack
= new LikeBack(LikeBack::AllButtons
, /*showBarByDefault=*/false, Global::config(), Global::about());
389 Global::likeBack
->setServer("basket.linux62.org", "/likeback/send.php");
391 // There are too much comments, and people reading comments are more and more international, so we accept only English:
392 // Global::likeBack->setAcceptedLanguages(QStringList::split(";", "en;fr"), i18n("Please write in English or French."));
395 // Global::likeBack->disableBar(); // See BNPView::shown() and BNPView::hide().
397 Global::likeBack
->sendACommentAction(actionCollection()); // Just create it!
400 /// What's This Help for the tree:
401 QWhatsThis::add(m_tree
, i18n(
402 "<h2>Basket Tree</h2>"
403 "Here is the list of your baskets. "
404 "You can organize your data by putting them in different baskets. "
405 "You can group baskets by subject by creating new baskets inside others. "
406 "You can browse between them by clicking a basket to open it, or reorganize them using drag and drop."));
408 setTreePlacement(Settings::treeOnLeft());
411 void BNPView::setupActions()
413 m_actSaveAsArchive
= new KAction( i18n("&Basket Archive..."), "baskets", 0,
414 this, SLOT(saveAsArchive()), actionCollection(), "basket_export_basket_archive" );
415 m_actOpenArchive
= new KAction( i18n("&Basket Archive..."), "baskets", 0,
416 this, SLOT(openArchive()), actionCollection(), "basket_import_basket_archive" );
418 m_actHideWindow
= new KAction( i18n("&Hide Window"), "", KStdAccel::shortcut(KStdAccel::Close
),
419 this, SLOT(hideOnEscape()), actionCollection(), "window_hide" );
420 m_actHideWindow
->setEnabled(Settings::useSystray()); // Init here !
422 m_actExportToHtml
= new KAction( i18n("&HTML Web Page..."), "html", 0,
423 this, SLOT(exportToHTML()), actionCollection(), "basket_export_html" );
424 new KAction( i18n("K&Notes"), "knotes", 0,
425 this, SLOT(importKNotes()), actionCollection(), "basket_import_knotes" );
426 new KAction( i18n("K&Jots"), "kjots", 0,
427 this, SLOT(importKJots()), actionCollection(), "basket_import_kjots" );
428 new KAction( i18n("&KnowIt..."), "knowit", 0,
429 this, SLOT(importKnowIt()), actionCollection(), "basket_import_knowit" );
430 new KAction( i18n("Tux&Cards..."), "tuxcards", 0,
431 this, SLOT(importTuxCards()), actionCollection(), "basket_import_tuxcards" );
432 new KAction( i18n("&Sticky Notes"), "gnome", 0,
433 this, SLOT(importStickyNotes()), actionCollection(), "basket_import_sticky_notes" );
434 new KAction( i18n("&Tomboy"), "tintin", 0,
435 this, SLOT(importTomboy()), actionCollection(), "basket_import_tomboy" );
436 new KAction( i18n("Text &File..."), "txt", 0,
437 this, SLOT(importTextFile()), actionCollection(), "basket_import_text_file" );
439 new KAction( i18n("&Backup && Restore..."), "", 0,
440 this, SLOT(backupRestore()), actionCollection(), "basket_backup_restore" );
442 /** Note : ****************************************************************/
444 m_actDelNote
= new KAction( i18n("D&elete"), "editdelete", "Delete",
445 this, SLOT(delNote()), actionCollection(), "edit_delete" );
446 m_actCutNote
= KStdAction::cut( this, SLOT(cutNote()), actionCollection() );
447 m_actCopyNote
= KStdAction::copy( this, SLOT(copyNote()), actionCollection() );
449 m_actSelectAll
= KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection() );
450 m_actSelectAll
->setStatusText( i18n( "Selects all notes" ) );
451 m_actUnselectAll
= new KAction( i18n( "U&nselect All" ), "", this, SLOT( slotUnselectAll() ),
452 actionCollection(), "edit_unselect_all" );
453 m_actUnselectAll
->setStatusText( i18n( "Unselects all selected notes" ) );
454 m_actInvertSelection
= new KAction( i18n( "&Invert Selection" ), CTRL
+Key_Asterisk
,
455 this, SLOT( slotInvertSelection() ),
456 actionCollection(), "edit_invert_selection" );
457 m_actInvertSelection
->setStatusText( i18n( "Inverts the current selection of notes" ) );
459 m_actEditNote
= new KAction( i18n("Verb; not Menu", "&Edit..."), "edit", "Return",
460 this, SLOT(editNote()), actionCollection(), "note_edit" );
462 m_actOpenNote
= KStdAction::open( this, SLOT(openNote()), actionCollection(), "note_open" );
463 m_actOpenNote
->setIcon("window_new");
464 m_actOpenNote
->setText(i18n("&Open"));
465 m_actOpenNote
->setShortcut("F9");
467 m_actOpenNoteWith
= new KAction( i18n("Open &With..."), "", "Shift+F9",
468 this, SLOT(openNoteWith()), actionCollection(), "note_open_with" );
469 m_actSaveNoteAs
= KStdAction::saveAs( this, SLOT(saveNoteAs()), actionCollection(), "note_save_to_file" );
470 m_actSaveNoteAs
->setIcon("");
471 m_actSaveNoteAs
->setText(i18n("&Save to File..."));
472 m_actSaveNoteAs
->setShortcut("F10");
474 m_actGroup
= new KAction( i18n("&Group"), "attach", "Ctrl+G",
475 this, SLOT(noteGroup()), actionCollection(), "note_group" );
476 m_actUngroup
= new KAction( i18n("U&ngroup"), "", "Ctrl+Shift+G",
477 this, SLOT(noteUngroup()), actionCollection(), "note_ungroup" );
479 m_actMoveOnTop
= new KAction( i18n("Move on &Top"), "2uparrow", "Ctrl+Shift+Home",
480 this, SLOT(moveOnTop()), actionCollection(), "note_move_top" );
481 m_actMoveNoteUp
= new KAction( i18n("Move &Up"), "1uparrow", "Ctrl+Shift+Up",
482 this, SLOT(moveNoteUp()), actionCollection(), "note_move_up" );
483 m_actMoveNoteDown
= new KAction( i18n("Move &Down"), "1downarrow", "Ctrl+Shift+Down",
484 this, SLOT(moveNoteDown()), actionCollection(), "note_move_down" );
485 m_actMoveOnBottom
= new KAction( i18n("Move on &Bottom"), "2downarrow", "Ctrl+Shift+End",
486 this, SLOT(moveOnBottom()), actionCollection(), "note_move_bottom" );
487 #if KDE_IS_VERSION( 3, 1, 90 ) // KDE 3.2.x
488 m_actPaste
= KStdAction::pasteText( this, SLOT(pasteInCurrentBasket()), actionCollection() );
490 m_actPaste
= KStdAction::paste( this, SLOT(pasteInCurrentBasket()), actionCollection() );
493 /** Insert : **************************************************************/
495 QSignalMapper
*insertEmptyMapper
= new QSignalMapper(this);
496 QSignalMapper
*insertWizardMapper
= new QSignalMapper(this);
497 connect( insertEmptyMapper
, SIGNAL(mapped(int)), this, SLOT(insertEmpty(int)) );
498 connect( insertWizardMapper
, SIGNAL(mapped(int)), this, SLOT(insertWizard(int)) );
500 // m_actInsertText = new KAction( i18n("Plai&n Text"), "text", "Ctrl+T", actionCollection(), "insert_text" );
501 m_actInsertHtml
= new KAction( i18n("&Text"), "html", "Insert", actionCollection(), "insert_html" );
502 m_actInsertLink
= new KAction( i18n("&Link"), "link", "Ctrl+Y", actionCollection(), "insert_link" );
503 m_actInsertImage
= new KAction( i18n("&Image"), "image", "", actionCollection(), "insert_image" );
504 m_actInsertColor
= new KAction( i18n("&Color"), "colorset", "", actionCollection(), "insert_color" );
505 m_actInsertLauncher
=new KAction( i18n("L&auncher"), "launch", "", actionCollection(), "insert_launcher" );
507 m_actImportKMenu
= new KAction( i18n("Import Launcher from &KDE Menu..."), "kmenu", "", actionCollection(), "insert_kmenu" );
508 m_actImportIcon
= new KAction( i18n("Im&port Icon..."), "icons", "", actionCollection(), "insert_icon" );
509 m_actLoadFile
= new KAction( i18n("Load From &File..."), "fileimport", "", actionCollection(), "insert_from_file" );
511 // connect( m_actInsertText, SIGNAL(activated()), insertEmptyMapper, SLOT(map()) );
512 connect( m_actInsertHtml
, SIGNAL(activated()), insertEmptyMapper
, SLOT(map()) );
513 connect( m_actInsertImage
, SIGNAL(activated()), insertEmptyMapper
, SLOT(map()) );
514 connect( m_actInsertLink
, SIGNAL(activated()), insertEmptyMapper
, SLOT(map()) );
515 connect( m_actInsertColor
, SIGNAL(activated()), insertEmptyMapper
, SLOT(map()) );
516 connect( m_actInsertLauncher
, SIGNAL(activated()), insertEmptyMapper
, SLOT(map()) );
517 // insertEmptyMapper->setMapping(m_actInsertText, NoteType::Text );
518 insertEmptyMapper
->setMapping(m_actInsertHtml
, NoteType::Html
);
519 insertEmptyMapper
->setMapping(m_actInsertImage
, NoteType::Image
);
520 insertEmptyMapper
->setMapping(m_actInsertLink
, NoteType::Link
);
521 insertEmptyMapper
->setMapping(m_actInsertColor
, NoteType::Color
);
522 insertEmptyMapper
->setMapping(m_actInsertLauncher
, NoteType::Launcher
);
524 connect( m_actImportKMenu
, SIGNAL(activated()), insertWizardMapper
, SLOT(map()) );
525 connect( m_actImportIcon
, SIGNAL(activated()), insertWizardMapper
, SLOT(map()) );
526 connect( m_actLoadFile
, SIGNAL(activated()), insertWizardMapper
, SLOT(map()) );
527 insertWizardMapper
->setMapping(m_actImportKMenu
, 1 );
528 insertWizardMapper
->setMapping(m_actImportIcon
, 2 );
529 insertWizardMapper
->setMapping(m_actLoadFile
, 3 );
531 m_colorPicker
= new DesktopColorPicker();
532 m_actColorPicker
= new KAction( i18n("C&olor from Screen"), "kcolorchooser", "",
533 this, SLOT(slotColorFromScreen()), actionCollection(), "insert_screen_color" );
534 connect( m_colorPicker
, SIGNAL(pickedColor(const QColor
&)), this, SLOT(colorPicked(const QColor
&)) );
535 connect( m_colorPicker
, SIGNAL(canceledPick()), this, SLOT(colorPickingCanceled()) );
537 m_actGrabScreenshot
= new KAction( i18n("Grab Screen &Zone"), "ksnapshot", "",
538 this, SLOT(grabScreenshot()), actionCollection(), "insert_screen_capture" );
539 //connect( m_actGrabScreenshot, SIGNAL(regionGrabbed(const QPixmap&)), this, SLOT(screenshotGrabbed(const QPixmap&)) );
540 //connect( m_colorPicker, SIGNAL(canceledPick()), this, SLOT(colorPickingCanceled()) );
542 // m_insertActions.append( m_actInsertText );
543 m_insertActions
.append( m_actInsertHtml
);
544 m_insertActions
.append( m_actInsertLink
);
545 m_insertActions
.append( m_actInsertImage
);
546 m_insertActions
.append( m_actInsertColor
);
547 m_insertActions
.append( m_actImportKMenu
);
548 m_insertActions
.append( m_actInsertLauncher
);
549 m_insertActions
.append( m_actImportIcon
);
550 m_insertActions
.append( m_actLoadFile
);
551 m_insertActions
.append( m_actColorPicker
);
552 m_insertActions
.append( m_actGrabScreenshot
);
554 /** Basket : **************************************************************/
556 // At this stage, main.cpp has not set kapp->mainWidget(), so Global::runInsideKontact()
557 // returns true. We do it ourself:
558 bool runInsideKontact
= true;
559 QWidget
*parentWidget
= (QWidget
*) parent();
560 while (parentWidget
) {
561 if (parentWidget
->inherits("MainWindow"))
562 runInsideKontact
= false;
563 parentWidget
= (QWidget
*) parentWidget
->parent();
566 // Use the "basket" incon in Kontact so it is consistent with the Kontact "New..." icon
567 actNewBasket
= new KAction( i18n("&New Basket..."), (runInsideKontact
? "basket" : "filenew"), KStdAccel::shortcut(KStdAccel::New
),
568 this, SLOT(askNewBasket()), actionCollection(), "basket_new" );
569 actNewSubBasket
= new KAction( i18n("New &Sub-Basket..."), "", "Ctrl+Shift+N",
570 this, SLOT(askNewSubBasket()), actionCollection(), "basket_new_sub" );
571 actNewSiblingBasket
= new KAction( i18n("New Si&bling Basket..."), "", "",
572 this, SLOT(askNewSiblingBasket()), actionCollection(), "basket_new_sibling" );
574 KActionMenu
*newBasketMenu
= new KActionMenu(i18n("&New"), "filenew", actionCollection(), "basket_new_menu");
575 newBasketMenu
->insert(actNewBasket
);
576 newBasketMenu
->insert(actNewSubBasket
);
577 newBasketMenu
->insert(actNewSiblingBasket
);
578 connect( newBasketMenu
, SIGNAL(activated()), this, SLOT(askNewBasket()) );
580 m_actPropBasket
= new KAction( i18n("&Properties..."), "misc", "F2",
581 this, SLOT(propBasket()), actionCollection(), "basket_properties" );
582 m_actDelBasket
= new KAction( i18n("Remove Basket", "&Remove"), "", 0,
583 this, SLOT(delBasket()), actionCollection(), "basket_remove" );
585 m_actPassBasket
= new KAction( i18n("Password protection", "Pass&word..."), "", 0,
586 this, SLOT(password()), actionCollection(), "basket_password" );
587 m_actLockBasket
= new KAction( i18n("Lock Basket", "&Lock"), "", "Ctrl+L",
588 this, SLOT(lockBasket()), actionCollection(), "basket_lock" );
590 /** Edit : ****************************************************************/
592 //m_actUndo = KStdAction::undo( this, SLOT(undo()), actionCollection() );
593 //m_actUndo->setEnabled(false); // Not yet implemented !
594 //m_actRedo = KStdAction::redo( this, SLOT(redo()), actionCollection() );
595 //m_actRedo->setEnabled(false); // Not yet implemented !
597 m_actShowFilter
= new KToggleAction( i18n("&Filter"), "filter", KStdAccel::shortcut(KStdAccel::Find
),
598 actionCollection(), "edit_filter" );
599 connect( m_actShowFilter
, SIGNAL(toggled(bool)), this, SLOT(showHideFilterBar(bool)) );
601 m_actFilterAllBaskets
= new KToggleAction( i18n("Filter all &Baskets"), "find", "Ctrl+Shift+F",
602 actionCollection(), "edit_filter_all_baskets" );
603 connect( m_actFilterAllBaskets
, SIGNAL(toggled(bool)), this, SLOT(toggleFilterAllBaskets(bool)) );
605 m_actResetFilter
= new KAction( i18n( "&Reset Filter" ), "locationbar_erase", "Ctrl+R",
606 this, SLOT( slotResetFilter() ), actionCollection(), "edit_filter_reset" );
608 /** Go : ******************************************************************/
610 m_actPreviousBasket
= new KAction( i18n( "&Previous Basket" ), "up", "Alt+Up",
611 this, SLOT(goToPreviousBasket()), actionCollection(), "go_basket_previous" );
612 m_actNextBasket
= new KAction( i18n( "&Next Basket" ), "down", "Alt+Down",
613 this, SLOT(goToNextBasket()), actionCollection(), "go_basket_next" );
614 m_actFoldBasket
= new KAction( i18n( "&Fold Basket" ), "back", "Alt+Left",
615 this, SLOT(foldBasket()), actionCollection(), "go_basket_fold" );
616 m_actExpandBasket
= new KAction( i18n( "&Expand Basket" ), "forward", "Alt+Right",
617 this, SLOT(expandBasket()), actionCollection(), "go_basket_expand" );
619 // m_convertTexts = new KAction( i18n("Convert text notes to rich text notes"), "compfile", "",
620 // this, SLOT(convertTexts()), actionCollection(), "beta_convert_texts" );
622 InlineEditors::instance()->initToolBars(actionCollection());
624 actConfigGlobalShortcuts
= KStdAction::keyBindings(this, SLOT(showGlobalShortcutsSettingsDialog()),
625 actionCollection(), "options_configure_global_keybinding");
626 actConfigGlobalShortcuts
->setText(i18n("Configure &Global Shortcuts..."));
628 /** Help : ****************************************************************/
630 new KAction( i18n("&Welcome Baskets"), "", "", this, SLOT(addWelcomeBaskets()), actionCollection(), "help_welcome_baskets" );
633 QListViewItem
* BNPView::firstListViewItem()
635 return m_tree
->firstChild();
638 void BNPView::slotShowProperties(QListViewItem
*item
, const QPoint
&, int)
644 void BNPView::slotMouseButtonPressed(int button
, QListViewItem
*item
, const QPoint
&/*pos*/, int /*column*/)
646 if (item
&& (button
& Qt::MidButton
)) {
647 // TODO: Paste into ((BasketListViewItem*)listViewItem)->basket()
651 void BNPView::slotContextMenu(KListView */
*listView*/
, QListViewItem
*item
, const QPoint
&pos
)
655 Basket
* basket
= ((BasketListViewItem
*)item
)->basket();
657 setCurrentBasket(basket
);
658 menuName
= "basket_popup";
660 menuName
= "tab_bar_popup";
662 * "File -> New" create a new basket with the same parent basket as the the current one.
663 * But when invoked when right-clicking the empty area at the bottom of the basket tree,
664 * it is obvious the user want to create a new basket at the bottom of the tree (with no parent).
665 * So we set a temporary variable during the time the popup menu is shown,
666 * so the slot askNewBasket() will do the right thing:
671 QPopupMenu
*menu
= popupMenu(menuName
);
672 connect( menu
, SIGNAL(aboutToHide()), this, SLOT(aboutToHideNewBasketPopup()) );
678 DEBUG_WIN
<< "Basket Tree: Saving...";
681 QDomDocument
document("basketTree");
682 QDomElement root
= document
.createElement("basketTree");
683 document
.appendChild(root
);
686 save(m_tree
->firstChild(), document
, root
);
689 Basket::safelySaveToFile(Global::basketsFolder() + "baskets.xml", "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + document
.toString());
690 // QFile file(Global::basketsFolder() + "baskets.xml");
691 // if (file.open(IO_WriteOnly)) {
692 // QTextStream stream(&file);
693 // stream.setEncoding(QTextStream::UnicodeUTF8);
694 // QString xml = document.toString();
695 // stream << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
701 void BNPView::save(QListViewItem
*firstItem
, QDomDocument
&document
, QDomElement
&parentElement
)
703 QListViewItem
*item
= firstItem
;
705 // Basket *basket = ((BasketListViewItem*)item)->basket();
706 QDomElement basketElement
= this->basketElement(item
, document
, parentElement
);
708 QDomElement basketElement = document.createElement("basket");
709 parentElement.appendChild(basketElement);
711 basketElement.setAttribute("folderName", basket->folderName());
712 if (item->firstChild()) // If it can be expanded/folded:
713 basketElement.setAttribute("folded", XMLWork::trueOrFalse(!item->isOpen()));
714 if (((BasketListViewItem*)item)->isCurrentBasket())
715 basketElement.setAttribute("lastOpened", "true");
717 QDomElement properties = document.createElement("properties");
718 basketElement.appendChild(properties);
719 basket->saveProperties(document, properties);
721 // Save Child Basket:
722 if (item
->firstChild())
723 save(item
->firstChild(), document
, basketElement
);
725 item
= item
->nextSibling();
729 QDomElement
BNPView::basketElement(QListViewItem
*item
, QDomDocument
&document
, QDomElement
&parentElement
)
731 Basket
*basket
= ((BasketListViewItem
*)item
)->basket();
732 QDomElement basketElement
= document
.createElement("basket");
733 parentElement
.appendChild(basketElement
);
735 basketElement
.setAttribute("folderName", basket
->folderName());
736 if (item
->firstChild()) // If it can be expanded/folded:
737 basketElement
.setAttribute("folded", XMLWork::trueOrFalse(!item
->isOpen()));
738 if (((BasketListViewItem
*)item
)->isCurrentBasket())
739 basketElement
.setAttribute("lastOpened", "true");
741 QDomElement properties
= document
.createElement("properties");
742 basketElement
.appendChild(properties
);
743 basket
->saveProperties(document
, properties
);
744 return basketElement
;
747 void BNPView::saveSubHierarchy(QListViewItem
*item
, QDomDocument
&document
, QDomElement
&parentElement
, bool recursive
)
749 QDomElement element
= basketElement(item
, document
, parentElement
);
750 if (recursive
&& item
->firstChild())
751 save(item
->firstChild(), document
, element
);
756 QDomDocument
*doc
= XMLWork::openFile("basketTree", Global::basketsFolder() + "baskets.xml");
757 //BEGIN Compatibility with 0.6.0 Pre-Alpha versions:
759 doc
= XMLWork::openFile("basketsTree", Global::basketsFolder() + "baskets.xml");
762 QDomElement docElem
= doc
->documentElement();
763 load(m_tree
, 0L, docElem
);
768 void BNPView::load(KListView */
*listView*/
, QListViewItem
*item
, const QDomElement
&baskets
)
770 QDomNode n
= baskets
.firstChild();
771 while ( ! n
.isNull() ) {
772 QDomElement element
= n
.toElement();
773 if ( (!element
.isNull()) && element
.tagName() == "basket" ) {
774 QString folderName
= element
.attribute("folderName");
775 if (!folderName
.isEmpty()) {
776 Basket
*basket
= loadBasket(folderName
);
777 BasketListViewItem
*basketItem
= appendBasket(basket
, item
);
778 basketItem
->setOpen(!XMLWork::trueOrFalse(element
.attribute("folded", "false"), false));
779 basket
->loadProperties(XMLWork::getElement(element
, "properties"));
780 if (XMLWork::trueOrFalse(element
.attribute("lastOpened", element
.attribute("lastOpenned", "false")), false)) // Compat with 0.6.0-Alphas
781 setCurrentBasket(basket
);
783 load(/*(QListView*)*/0L, basketItem
, element
);
790 Basket
* BNPView::loadBasket(const QString
&folderName
)
792 if (folderName
.isEmpty())
795 DecoratedBasket
*decoBasket
= new DecoratedBasket(m_stack
, folderName
);
796 Basket
*basket
= decoBasket
->basket();
797 m_stack
->addWidget(decoBasket
);
798 connect( basket
, SIGNAL(countsChanged(Basket
*)), this, SLOT(countsChanged(Basket
*)) );
799 // Important: Create listViewItem and connect signal BEFORE loadProperties(), so we get the listViewItem updated without extra work:
800 connect( basket
, SIGNAL(propertiesChanged(Basket
*)), this, SLOT(updateBasketListViewItem(Basket
*)) );
802 connect( basket
->decoration()->filterBar(), SIGNAL(newFilter(const FilterData
&)), this, SLOT(newFilterFromFilterBar()) );
807 int BNPView::basketCount(QListViewItem
*parent
)
811 QListViewItem
*item
= (parent
? parent
->firstChild() : m_tree
->firstChild());
813 count
+= 1 + basketCount(item
);
814 item
= item
->nextSibling();
820 bool BNPView::canFold()
822 BasketListViewItem
*item
= listViewItemForBasket(currentBasket());
825 return item
->parent() || (item
->firstChild() && item
->isOpen());
828 bool BNPView::canExpand()
830 BasketListViewItem
*item
= listViewItemForBasket(currentBasket());
833 return item
->firstChild();
836 BasketListViewItem
* BNPView::appendBasket(Basket
*basket
, QListViewItem
*parentItem
)
838 BasketListViewItem
*newBasketItem
;
840 newBasketItem
= new BasketListViewItem(parentItem
, ((BasketListViewItem
*)parentItem
)->lastChild(), basket
);
842 QListViewItem
*child
= m_tree
->firstChild();
843 QListViewItem
*lastChild
= 0;
846 child
= child
->nextSibling();
848 newBasketItem
= new BasketListViewItem(m_tree
, lastChild
, basket
);
851 emit
basketNumberChanged(basketCount());
853 return newBasketItem
;
856 void BNPView::loadNewBasket(const QString
&folderName
, const QDomElement
&properties
, Basket
*parent
)
858 Basket
*basket
= loadBasket(folderName
);
859 appendBasket(basket
, (basket
? listViewItemForBasket(parent
) : 0));
860 basket
->loadProperties(properties
);
861 setCurrentBasket(basket
);
865 BasketListViewItem
* BNPView::lastListViewItem()
867 QListViewItem
*child
= m_tree
->firstChild();
868 QListViewItem
*lastChild
= 0;
869 // Set lastChild to the last primary child of the list view:
872 child
= child
->nextSibling();
874 // If this child have child(s), recursivly browse through them to find the real last one:
875 while (lastChild
&& lastChild
->firstChild()) {
876 child
= lastChild
->firstChild();
879 child
= child
->nextSibling();
882 return (BasketListViewItem
*)lastChild
;
885 void BNPView::goToPreviousBasket()
887 if (!m_tree
->firstChild())
890 BasketListViewItem
*item
= listViewItemForBasket(currentBasket());
891 BasketListViewItem
*toSwitch
= item
->shownItemAbove();
893 toSwitch
= lastListViewItem();
894 if (toSwitch
&& !toSwitch
->isShown())
895 toSwitch
= toSwitch
->shownItemAbove();
899 setCurrentBasket(toSwitch
->basket());
901 if (Settings::usePassivePopup())
902 showPassiveContent();
905 void BNPView::goToNextBasket()
907 if (!m_tree
->firstChild())
910 BasketListViewItem
*item
= listViewItemForBasket(currentBasket());
911 BasketListViewItem
*toSwitch
= item
->shownItemBelow();
913 toSwitch
= ((BasketListViewItem
*)m_tree
->firstChild());
916 setCurrentBasket(toSwitch
->basket());
918 if (Settings::usePassivePopup())
919 showPassiveContent();
922 void BNPView::foldBasket()
924 BasketListViewItem
*item
= listViewItemForBasket(currentBasket());
925 if (item
&& !item
->firstChild())
926 item
->setOpen(false); // If Alt+Left is hitted and there is nothing to close, make sure the focus will go to the parent basket
928 QKeyEvent
* keyEvent
= new QKeyEvent(QEvent::KeyPress
, Qt::Key_Left
, 0, 0);
929 QApplication::postEvent(m_tree
, keyEvent
);
932 void BNPView::expandBasket()
934 QKeyEvent
* keyEvent
= new QKeyEvent(QEvent::KeyPress
, Qt::Key_Right
, 0, 0);
935 QApplication::postEvent(m_tree
, keyEvent
);
938 void BNPView::closeAllEditors()
940 QListViewItemIterator
it(m_tree
);
941 while (it
.current()) {
942 BasketListViewItem
*item
= (BasketListViewItem
*)(it
.current());
943 item
->basket()->closeEditor();
948 bool BNPView::convertTexts()
950 bool convertedNotes
= false;
951 KProgressDialog
dialog(
954 /*caption=*/i18n("Plain Text Notes Conversion"),
955 /*text=*/i18n("Converting plain text notes to rich text ones..."),
957 dialog
.progressBar()->setTotalSteps(basketCount());
958 dialog
.show(); //setMinimumDuration(50/*ms*/);
960 QListViewItemIterator
it(m_tree
);
961 while (it
.current()) {
962 BasketListViewItem
*item
= (BasketListViewItem
*)(it
.current());
963 if (item
->basket()->convertTexts())
964 convertedNotes
= true;
965 dialog
.progressBar()->advance(1);
966 if (dialog
.wasCancelled())
971 return convertedNotes
;
974 /** isRunning is to avoid recursive calls because this method can be called
975 * when clicking the menu action or when using the filter-bar icon... either of those calls
976 * call the other to be checked... and it can cause recursive calls.
977 * PS: Uggly hack? Yes, I think so :-)
979 void BNPView::toggleFilterAllBaskets(bool doFilter
)
981 static bool isRunning
= false;
987 m_actFilterAllBaskets
->setChecked(doFilter
);
988 //currentBasket()->decoration()->filterBar()->setFilterAll(doFilter);
990 // Basket *current = currentBasket();
991 QListViewItemIterator
it(m_tree
);
992 while (it
.current()) {
993 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
994 item
->basket()->decoration()->filterBar()->setFilterAll(doFilter
);
998 // Protection is not necessary anymore:
1002 currentBasket()->decoration()->filterBar()->setEditFocus();
1004 // Filter every baskets:
1008 /** This function can be called recursively because we call kapp->processEvents().
1009 * If this function is called whereas another "instance" is running,
1010 * this new "instance" leave and set up a flag that is read by the first "instance"
1011 * to know it should re-begin the work.
1012 * PS: Yes, that's a very lame pseudo-threading but that works, and it's programmer-efforts cheap :-)
1014 void BNPView::newFilter()
1016 static bool alreadyEntered
= false;
1017 static bool shouldRestart
= false;
1019 if (alreadyEntered
) {
1020 shouldRestart
= true;
1023 alreadyEntered
= true;
1024 shouldRestart
= false;
1026 Basket
*current
= currentBasket();
1027 const FilterData
&filterData
= current
->decoration()->filterBar()->filterData();
1029 // Set the filter data for every other baskets, or reset the filter for every other baskets if we just disabled the filterInAllBaskets:
1030 QListViewItemIterator
it(m_tree
);
1031 while (it
.current()) {
1032 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
1033 if (item
->basket() != current
)
1034 if (isFilteringAllBaskets())
1035 item
->basket()->decoration()->filterBar()->setFilterData(filterData
); // Set the new FilterData for every other baskets
1037 item
->basket()->decoration()->filterBar()->setFilterData(FilterData()); // We just disabled the global filtering: remove the FilterData
1041 // Show/hide the "little filter icons" (during basket load)
1042 // or the "little numbers" (to show number of found notes in the baskets) is the tree:
1043 m_tree
->triggerUpdate();
1044 kapp
->processEvents();
1046 // Load every baskets for filtering, if they are not already loaded, and if necessary:
1047 if (filterData
.isFiltering
) {
1048 Basket
*current
= currentBasket();
1049 QListViewItemIterator
it(m_tree
);
1050 while (it
.current()) {
1051 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
1052 if (item
->basket() != current
) {
1053 Basket
*basket
= item
->basket();
1054 if (!basket
->loadingLaunched() && !basket
->isLocked())
1056 basket
->filterAgain();
1057 m_tree
->triggerUpdate();
1058 kapp
->processEvents();
1059 if (shouldRestart
) {
1060 alreadyEntered
= false;
1061 shouldRestart
= false;
1070 m_tree
->triggerUpdate();
1071 // kapp->processEvents();
1073 alreadyEntered
= false;
1074 shouldRestart
= false;
1077 void BNPView::newFilterFromFilterBar()
1079 if (isFilteringAllBaskets())
1080 QTimer::singleShot(0, this, SLOT(newFilter())); // Keep time for the QLineEdit to display the filtered character and refresh correctly!
1083 bool BNPView::isFilteringAllBaskets()
1085 return m_actFilterAllBaskets
->isChecked();
1089 BasketListViewItem
* BNPView::listViewItemForBasket(Basket
*basket
)
1091 QListViewItemIterator
it(m_tree
);
1092 while (it
.current()) {
1093 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
1094 if (item
->basket() == basket
)
1101 Basket
* BNPView::currentBasket()
1103 DecoratedBasket
*decoBasket
= (DecoratedBasket
*)m_stack
->visibleWidget();
1105 return decoBasket
->basket();
1110 Basket
* BNPView::parentBasketOf(Basket
*basket
)
1112 BasketListViewItem
*item
= (BasketListViewItem
*)(listViewItemForBasket(basket
)->parent());
1114 return item
->basket();
1119 void BNPView::setCurrentBasket(Basket
*basket
)
1121 if (currentBasket() == basket
)
1124 if (currentBasket())
1125 currentBasket()->closeBasket();
1128 basket
->aboutToBeActivated();
1130 BasketListViewItem
*item
= listViewItemForBasket(basket
);
1132 m_tree
->setSelected(item
, true);
1133 item
->ensureVisible();
1134 m_stack
->raiseWidget(basket
->decoration());
1135 // If the window has changed size, only the current basket receive the event,
1136 // the others will receive ony one just before they are shown.
1137 // But this triggers unwanted animations, so we eliminate it:
1138 basket
->relayoutNotes(/*animate=*/false);
1139 basket
->openBasket();
1140 setCaption(item
->basket()->basketName());
1141 countsChanged(basket
);
1142 updateStatusBarHint();
1143 if (Global::systemTray
)
1144 Global::systemTray
->updateToolTip();
1145 m_tree
->ensureItemVisible(m_tree
->currentItem());
1146 item
->basket()->setFocus();
1148 m_tree
->viewport()->update();
1149 emit
basketChanged();
1152 void BNPView::removeBasket(Basket
*basket
)
1154 if (basket
->isDuringEdit())
1155 basket
->closeEditor();
1157 // Find a new basket to switch to and select it.
1158 // Strategy: get the next sibling, or the previous one if not found.
1159 // If there is no such one, get the parent basket:
1160 BasketListViewItem
*basketItem
= listViewItemForBasket(basket
);
1161 BasketListViewItem
*nextBasketItem
= (BasketListViewItem
*)(basketItem
->nextSibling());
1162 if (!nextBasketItem
)
1163 nextBasketItem
= basketItem
->prevSibling();
1164 if (!nextBasketItem
)
1165 nextBasketItem
= (BasketListViewItem
*)(basketItem
->parent());
1168 setCurrentBasket(nextBasketItem
->basket());
1170 // Remove from the view:
1171 basket
->unsubscribeBackgroundImages();
1172 m_stack
->removeWidget(basket
->decoration());
1173 // delete basket->decoration();
1177 // If there is no basket anymore, add a new one:
1178 if (!nextBasketItem
)
1179 BasketFactory::newBasket(/*icon=*/"", /*name=*/i18n("General"), /*backgroundImage=*/"", /*backgroundColor=*/QColor(), /*textColor=*/QColor(), /*templateName=*/"1column", /*createIn=*/0);
1180 else // No need to save two times if we add a basket
1183 emit
basketNumberChanged(basketCount());
1186 void BNPView::setTreePlacement(bool onLeft
)
1189 moveToFirst(m_tree
);
1193 kapp
->postEvent( this, new QResizeEvent(size(), size()) );
1196 void BNPView::relayoutAllBaskets()
1198 QListViewItemIterator
it(m_tree
);
1199 while (it
.current()) {
1200 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
1201 //item->basket()->unbufferizeAll();
1202 item
->basket()->unsetNotesWidth();
1203 item
->basket()->relayoutNotes(true);
1208 void BNPView::recomputeAllStyles()
1210 QListViewItemIterator
it(m_tree
);
1211 while (it
.current()) {
1212 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
1213 item
->basket()->recomputeAllStyles();
1214 item
->basket()->unsetNotesWidth();
1215 item
->basket()->relayoutNotes(true);
1220 void BNPView::removedStates(const QValueList
<State
*> &deletedStates
)
1222 QListViewItemIterator
it(m_tree
);
1223 while (it
.current()) {
1224 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
1225 item
->basket()->removedStates(deletedStates
);
1230 void BNPView::linkLookChanged()
1232 QListViewItemIterator
it(m_tree
);
1233 while (it
.current()) {
1234 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
1235 item
->basket()->linkLookChanged();
1240 void BNPView::filterPlacementChanged(bool onTop
)
1242 QListViewItemIterator
it(m_tree
);
1243 while (it
.current()) {
1244 BasketListViewItem
*item
= static_cast<BasketListViewItem
*>(it
.current());
1245 DecoratedBasket
*decoration
= static_cast<DecoratedBasket
*>(item
->basket()->parent());
1246 decoration
->setFilterBarPosition(onTop
);
1251 void BNPView::updateBasketListViewItem(Basket
*basket
)
1253 BasketListViewItem
*item
= listViewItemForBasket(basket
);
1257 if (basket
== currentBasket()) {
1258 setCaption(basket
->basketName());
1259 if (Global::systemTray
)
1260 Global::systemTray
->updateToolTip();
1263 // Don't save if we are loading!
1268 void BNPView::needSave(QListViewItem
*)
1271 // A basket has been collapsed/expanded or a new one is select: this is not urgent:
1272 QTimer::singleShot(500/*ms*/, this, SLOT(save()));
1275 void BNPView::slotPressed(QListViewItem
*item
, const QPoint
&/*pos*/, int /*column*/)
1277 Basket
*basket
= currentBasket();
1281 // Impossible to Select no Basket:
1283 m_tree
->setSelected(listViewItemForBasket(basket
), true);
1284 else if (dynamic_cast<BasketListViewItem
*>(item
) != 0 && currentBasket() != ((BasketListViewItem
*)item
)->basket()) {
1285 setCurrentBasket( ((BasketListViewItem
*)item
)->basket() );
1291 DecoratedBasket
* BNPView::currentDecoratedBasket()
1293 if (currentBasket())
1294 return currentBasket()->decoration();
1299 // Redirected actions :
1301 void BNPView::exportToHTML() { HTMLExporter
exporter(currentBasket()); }
1302 void BNPView::editNote() { currentBasket()->noteEdit(); }
1303 void BNPView::cutNote() { currentBasket()->noteCut(); }
1304 void BNPView::copyNote() { currentBasket()->noteCopy(); }
1305 void BNPView::delNote() { currentBasket()->noteDelete(); }
1306 void BNPView::openNote() { currentBasket()->noteOpen(); }
1307 void BNPView::openNoteWith() { currentBasket()->noteOpenWith(); }
1308 void BNPView::saveNoteAs() { currentBasket()->noteSaveAs(); }
1309 void BNPView::noteGroup() { currentBasket()->noteGroup(); }
1310 void BNPView::noteUngroup() { currentBasket()->noteUngroup(); }
1311 void BNPView::moveOnTop() { currentBasket()->noteMoveOnTop(); }
1312 void BNPView::moveOnBottom() { currentBasket()->noteMoveOnBottom(); }
1313 void BNPView::moveNoteUp() { currentBasket()->noteMoveNoteUp(); }
1314 void BNPView::moveNoteDown() { currentBasket()->noteMoveNoteDown(); }
1315 void BNPView::slotSelectAll() { currentBasket()->selectAll(); }
1316 void BNPView::slotUnselectAll() { currentBasket()->unselectAll(); }
1317 void BNPView::slotInvertSelection() { currentBasket()->invertSelection(); }
1318 void BNPView::slotResetFilter() { currentDecoratedBasket()->resetFilter(); }
1320 void BNPView::importKJots() { SoftwareImporters::importKJots(); }
1321 void BNPView::importKNotes() { SoftwareImporters::importKNotes(); }
1322 void BNPView::importKnowIt() { SoftwareImporters::importKnowIt(); }
1323 void BNPView::importTuxCards() { SoftwareImporters::importTuxCards(); }
1324 void BNPView::importStickyNotes() { SoftwareImporters::importStickyNotes(); }
1325 void BNPView::importTomboy() { SoftwareImporters::importTomboy(); }
1326 void BNPView::importTextFile() { SoftwareImporters::importTextFile(); }
1328 void BNPView::backupRestore()
1330 BackupDialog dialog
;
1334 void BNPView::countsChanged(Basket
*basket
)
1336 if (basket
== currentBasket())
1337 notesStateChanged();
1340 void BNPView::notesStateChanged()
1342 Basket
*basket
= currentBasket();
1344 // Update statusbar message :
1345 if (currentBasket()->isLocked())
1346 setSelectionStatus(i18n("Locked"));
1347 else if (!basket
->isLoaded())
1348 setSelectionStatus(i18n("Loading..."));
1349 else if (basket
->count() == 0)
1350 setSelectionStatus(i18n("No notes"));
1352 QString count
= i18n("%n note", "%n notes", basket
->count() );
1353 QString selecteds
= i18n("%n selected", "%n selected", basket
->countSelecteds());
1354 QString showns
= (currentDecoratedBasket()->filterData().isFiltering
? i18n("all matches") : i18n("no filter"));
1355 if (basket
->countFounds() != basket
->count())
1356 showns
= i18n("%n match", "%n matches", basket
->countFounds());
1358 i18n("e.g. '18 notes, 10 matches, 5 selected'", "%1, %2, %3").arg(count
, showns
, selecteds
) );
1361 // If we added a note that match the global filter, update the count number in the tree:
1362 if (isFilteringAllBaskets())
1363 listViewItemForBasket(basket
)->listView()->triggerUpdate();
1365 if (currentBasket()->redirectEditActions()) {
1366 m_actSelectAll
->setEnabled( !currentBasket()->selectedAllTextInEditor() );
1367 m_actUnselectAll
->setEnabled( currentBasket()->hasSelectedTextInEditor() );
1369 m_actSelectAll
->setEnabled( basket
->countSelecteds() < basket
->countFounds() );
1370 m_actUnselectAll
->setEnabled( basket
->countSelecteds() > 0 );
1372 m_actInvertSelection
->setEnabled( basket
->countFounds() > 0 );
1374 updateNotesActions();
1377 void BNPView::updateNotesActions()
1379 bool isLocked
= currentBasket()->isLocked();
1380 bool oneSelected
= currentBasket()->countSelecteds() == 1;
1381 bool oneOrSeveralSelected
= currentBasket()->countSelecteds() >= 1;
1382 bool severalSelected
= currentBasket()->countSelecteds() >= 2;
1384 // FIXME: m_actCheckNotes is also modified in void BNPView::areSelectedNotesCheckedChanged(bool checked)
1385 // bool Basket::areSelectedNotesChecked() should return false if bool Basket::showCheckBoxes() is false
1386 // m_actCheckNotes->setChecked( oneOrSeveralSelected &&
1387 // currentBasket()->areSelectedNotesChecked() &&
1388 // currentBasket()->showCheckBoxes() );
1390 Note
*selectedGroup
= (severalSelected
? currentBasket()->selectedGroup() : 0);
1392 m_actEditNote
->setEnabled( !isLocked
&& oneSelected
&& !currentBasket()->isDuringEdit() );
1393 if (currentBasket()->redirectEditActions()) {
1394 m_actCutNote
->setEnabled( currentBasket()->hasSelectedTextInEditor() );
1395 m_actCopyNote
->setEnabled( currentBasket()->hasSelectedTextInEditor() );
1396 m_actPaste
->setEnabled( true );
1397 m_actDelNote
->setEnabled( currentBasket()->hasSelectedTextInEditor() );
1399 m_actCutNote
->setEnabled( !isLocked
&& oneOrSeveralSelected
);
1400 m_actCopyNote
->setEnabled( oneOrSeveralSelected
);
1401 m_actPaste
->setEnabled( !isLocked
);
1402 m_actDelNote
->setEnabled( !isLocked
&& oneOrSeveralSelected
);
1404 m_actOpenNote
->setEnabled( oneOrSeveralSelected
);
1405 m_actOpenNoteWith
->setEnabled( oneSelected
); // TODO: oneOrSeveralSelected IF SAME TYPE
1406 m_actSaveNoteAs
->setEnabled( oneSelected
); // IDEM?
1407 m_actGroup
->setEnabled( !isLocked
&& severalSelected
&& (!selectedGroup
|| selectedGroup
->isColumn()) );
1408 m_actUngroup
->setEnabled( !isLocked
&& selectedGroup
&& !selectedGroup
->isColumn() );
1409 m_actMoveOnTop
->setEnabled( !isLocked
&& oneOrSeveralSelected
&& !currentBasket()->isFreeLayout() );
1410 m_actMoveNoteUp
->setEnabled( !isLocked
&& oneOrSeveralSelected
); // TODO: Disable when unavailable!
1411 m_actMoveNoteDown
->setEnabled( !isLocked
&& oneOrSeveralSelected
);
1412 m_actMoveOnBottom
->setEnabled( !isLocked
&& oneOrSeveralSelected
&& !currentBasket()->isFreeLayout() );
1414 for (KAction
*action
= m_insertActions
.first(); action
; action
= m_insertActions
.next())
1415 action
->setEnabled( !isLocked
);
1417 // From the old Note::contextMenuEvent(...) :
1418 /* if (useFile() || m_type == Link) {
1419 m_type == Link ? i18n("&Open target") : i18n("&Open")
1420 m_type == Link ? i18n("Open target &with...") : i18n("Open &with...")
1421 m_type == Link ? i18n("&Save target as...") : i18n("&Save a copy as...")
1422 // If useFile() theire is always a file to open / open with / save, but :
1423 if (m_type == Link) {
1424 if (url().prettyURL().isEmpty() && runCommand().isEmpty()) // no URL nor runCommand :
1425 popupMenu->setItemEnabled(7, false); // no possible Open !
1426 if (url().prettyURL().isEmpty()) // no URL :
1427 popupMenu->setItemEnabled(8, false); // no possible Open with !
1428 if (url().prettyURL().isEmpty() || url().path().endsWith("/")) // no URL or target a folder :
1429 popupMenu->setItemEnabled(9, false); // not possible to save target file
1431 } else if (m_type != Color) {
1432 popupMenu->insertSeparator();
1433 popupMenu->insertItem( SmallIconSet("filesaveas"), i18n("&Save a copy as..."), this, SLOT(slotSaveAs()), 0, 10 );
1437 // BEGIN Color picker (code from KColorEdit):
1439 /* Activate the mode
1441 void BNPView::slotColorFromScreen(bool global
)
1443 m_colorPickWasGlobal
= global
;
1444 if (isMainWindowActive()) {
1445 if(Global::mainWindow()) Global::mainWindow()->hide();
1446 m_colorPickWasShown
= true;
1448 m_colorPickWasShown
= false;
1450 currentBasket()->saveInsertionData();
1451 m_colorPicker
->pickColor();
1453 /* m_gettingColorFromScreen = true;
1454 kapp->processEvents();
1455 QTimer::singleShot( 100, this, SLOT(grabColorFromScreen()) );*/
1458 void BNPView::slotColorFromScreenGlobal()
1460 slotColorFromScreen(true);
1463 void BNPView::colorPicked(const QColor
&color
)
1465 if (!currentBasket()->isLoaded()) {
1466 showPassiveLoading(currentBasket());
1467 currentBasket()->load();
1469 currentBasket()->insertColor(color
);
1471 if (m_colorPickWasShown
)
1474 if (Settings::usePassivePopup())
1475 showPassiveDropped(i18n("Picked color to basket <i>%1</i>"));
1478 void BNPView::colorPickingCanceled()
1480 if (m_colorPickWasShown
)
1484 void BNPView::slotConvertTexts()
1487 int result = KMessageBox::questionYesNoCancel(
1490 "<p>This will convert every text notes into rich text notes.<br>"
1491 "The content of the notes will not change and you will be able to apply formating to those notes.</p>"
1492 "<p>This process cannot be reverted back: you will not be able to convert the rich text notes to plain text ones later.</p>"
1493 "<p>As a beta-tester, you are strongly encouraged to do the convert process because it is to test if plain text notes are still needed.<br>"
1494 "If nobody complain about not having plain text notes anymore, then the final version is likely to not support plain text notes anymore.</p>"
1495 "<p><b>Which basket notes do you want to convert?</b></p>"
1497 i18n("Convert Text Notes"),
1498 KGuiItem(i18n("Only in the Current Basket")),
1499 KGuiItem(i18n("In Every Baskets"))
1501 if (result == KMessageBox::Cancel)
1505 bool conversionsDone
;
1506 // if (result == KMessageBox::Yes)
1507 // conversionsDone = currentBasket()->convertTexts();
1509 conversionsDone
= convertTexts();
1511 if (conversionsDone
)
1512 KMessageBox::information(this, i18n("The plain text notes have been converted to rich text."), i18n("Conversion Finished"));
1514 KMessageBox::information(this, i18n("There are no plain text notes to convert."), i18n("Conversion Finished"));
1517 QPopupMenu
* BNPView::popupMenu(const QString
&menuName
)
1519 QPopupMenu
*menu
= 0;
1520 bool hack
= false; // TODO fix this
1521 // When running in kontact and likeback Information message is shown
1522 // factory is 0. Don't show error then and don't crash either :-)
1526 KXMLGUIFactory
* factory
= m_guiClient
->factory();
1529 menu
= (QPopupMenu
*)factory
->container(menuName
, m_guiClient
);
1537 KStandardDirs stdDirs
;
1538 KMessageBox::error( this, i18n(
1539 "<p><b>The file basketui.rc seems to not exist or is too old.<br>"
1540 "%1 cannot run without it and will stop.</b></p>"
1541 "<p>Please check your installation of %2.</p>"
1542 "<p>If you do not have administrator access to install the application "
1543 "system wide, you can copy the file basketui.rc from the installation "
1544 "archive to the folder <a href='file://%3'>%4</a>.</p>"
1545 "<p>As last ressort, if you are sure the application is correctly installed "
1546 "but you had a preview version of it, try to remove the "
1547 "file %5basketui.rc</p>")
1548 .arg(kapp
->aboutData()->programName(), kapp
->aboutData()->programName(),
1549 stdDirs
.saveLocation("data", "basket/")).arg(stdDirs
.saveLocation("data", "basket/"), stdDirs
.saveLocation("data", "basket/")),
1550 i18n("Ressource not Found"), KMessageBox::AllowLink
);
1553 exit(1); // We SHOULD exit right now and abord everything because the caller except menu != 0 to not crash.
1555 menu
= new KPopupMenu
; // When running in kpart we cannot exit
1560 void BNPView::showHideFilterBar(bool show
, bool switchFocus
)
1562 // if (show != m_actShowFilter->isChecked())
1563 // m_actShowFilter->setChecked(show);
1564 m_actShowFilter
->setChecked(currentDecoratedBasket()->filterData().isFiltering
);
1566 currentDecoratedBasket()->setFilterBarShown(show
, switchFocus
);
1567 currentDecoratedBasket()->resetFilter();
1570 void BNPView::insertEmpty(int type
)
1572 if (currentBasket()->isLocked()) {
1573 showPassiveImpossible(i18n("Cannot add note."));
1576 currentBasket()->insertEmptyNote(type
);
1579 void BNPView::insertWizard(int type
)
1581 if (currentBasket()->isLocked()) {
1582 showPassiveImpossible(i18n("Cannot add note."));
1585 currentBasket()->insertWizard(type
);
1588 // BEGIN Screen Grabbing: // FIXME
1590 void BNPView::grabScreenshot(bool global
)
1592 if (m_regionGrabber
) {
1593 KWin::activateWindow(m_regionGrabber
->winId());
1597 // Delay before to take a screenshot because if we hide the main window OR the systray popup menu,
1598 // we should wait the windows below to be repainted!!!
1599 // A special case is where the action is triggered with the global keyboard shortcut.
1600 // In this case, global is true, and we don't wait.
1601 // In the future, if global is also defined for other cases, check for
1602 // enum KAction::ActivationReason { UnknownActivation, EmulatedActivation, AccelActivation, PopupMenuActivation, ToolBarActivation };
1603 int delay
= (isMainWindowActive() ? 500 : (global
/*kapp->activePopupWidget()*/ ? 0 : 200));
1605 m_colorPickWasGlobal
= global
;
1606 if (isMainWindowActive()) {
1607 if(Global::mainWindow()) Global::mainWindow()->hide();
1608 m_colorPickWasShown
= true;
1610 m_colorPickWasShown
= false;
1612 currentBasket()->saveInsertionData();
1613 m_regionGrabber
= new RegionGrabber(delay
);
1614 connect( m_regionGrabber
, SIGNAL(regionGrabbed(const QPixmap
&)), this, SLOT(screenshotGrabbed(const QPixmap
&)) );
1617 void BNPView::grabScreenshotGlobal()
1619 grabScreenshot(true);
1622 void BNPView::screenshotGrabbed(const QPixmap
&pixmap
)
1624 delete m_regionGrabber
;
1625 m_regionGrabber
= 0;
1627 // Cancelled (pressed Escape):
1628 if (pixmap
.isNull()) {
1629 if (m_colorPickWasShown
)
1634 if (!currentBasket()->isLoaded()) {
1635 showPassiveLoading(currentBasket());
1636 currentBasket()->load();
1638 currentBasket()->insertImage(pixmap
);
1640 if (m_colorPickWasShown
)
1643 if (Settings::usePassivePopup())
1644 showPassiveDropped(i18n("Grabbed screen zone to basket <i>%1</i>"));
1647 Basket
* BNPView::basketForFolderName(const QString
&folderName
)
1649 /* QPtrList<Basket> basketsList = listBaskets();
1651 for (basket = basketsList.first(); basket; basket = basketsList.next())
1652 if (basket->folderName() == folderName)
1656 QString name
= folderName
;
1657 if (!name
.endsWith("/"))
1660 QListViewItemIterator
it(m_tree
);
1661 while (it
.current()) {
1662 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
1663 if (item
->basket()->folderName() == name
)
1664 return item
->basket();
1672 Note
* BNPView::noteForFileName(const QString
&fileName
, Basket
&basket
, Note
* note
)
1675 note
= basket
.firstNote();
1676 if (note
->fullPath().endsWith(fileName
))
1678 Note
* child
= note
->firstChild();
1682 found
= noteForFileName(fileName
, basket
, child
);
1685 child
= child
->next();
1690 void BNPView::setFiltering(bool filtering
)
1692 m_actShowFilter
->setChecked(filtering
);
1693 m_actResetFilter
->setEnabled(filtering
);
1696 void BNPView::undo()
1701 void BNPView::redo()
1706 void BNPView::pasteToBasket(int /*index*/, QClipboard::Mode
/*mode*/)
1709 //basketAt(index)->pasteNote(mode);
1712 void BNPView::propBasket()
1714 BasketPropertiesDialog
dialog(currentBasket(), this);
1718 void BNPView::delBasket()
1720 // DecoratedBasket *decoBasket = currentDecoratedBasket();
1721 Basket
*basket
= currentBasket();
1724 KDialogBase
*dialog
= new KDialogBase(this, /*name=*/0, /*modal=*/true, /*caption=*/i18n("Delete Basket"),
1725 KDialogBase::User1
| KDialogBase::User2
| KDialogBase::No
, KDialogBase::User1
,
1726 /*separator=*/false,
1727 /*user1=*/KGuiItem(i18n("Delete Only that Basket")/*, icon=""*/),
1728 /*user2=*/KGuiItem(i18n("Delete Note & Children")/*, icon=""*/) );
1729 QStringList basketsList
;
1730 basketsList
.append("Basket 1");
1731 basketsList
.append(" Basket 2");
1732 basketsList
.append(" Basket 3");
1733 basketsList
.append(" Basket 4");
1734 KMessageBox::createKMessageBox(
1735 dialog
, QMessageBox::Information
,
1736 i18n("<qt>Do you really want to remove the basket <b>%1</b> and its contents?</qt>")
1737 .arg(Tools::textToHTMLWithoutP(basket
->basketName())),
1738 basketsList
, /*ask=*/"", /*checkboxReturn=*/0, /*options=*/KMessageBox::Notify
/*, const QString &details=QString::null*/);
1741 int really
= KMessageBox::questionYesNo( this,
1742 i18n("<qt>Do you really want to remove the basket <b>%1</b> and its contents?</qt>")
1743 .arg(Tools::textToHTMLWithoutP(basket
->basketName())),
1744 i18n("Remove Basket")
1745 #if KDE_IS_VERSION( 3, 2, 90 ) // KDE 3.3.x
1746 , KGuiItem(i18n("&Remove Basket"), "editdelete"), KStdGuiItem::cancel());
1751 if (really
== KMessageBox::No
)
1754 QStringList basketsList
= listViewItemForBasket(basket
)->childNamesTree();
1755 if (basketsList
.count() > 0) {
1756 int deleteChilds
= KMessageBox::questionYesNoList( this,
1757 i18n("<qt><b>%1</b> have the following children baskets.<br>Do you want to remove them too?</qt>")
1758 .arg(Tools::textToHTMLWithoutP(basket
->basketName())),
1760 i18n("Remove Children Baskets")
1761 #if KDE_IS_VERSION( 3, 2, 90 ) // KDE 3.3.x
1762 , KGuiItem(i18n("&Remove Children Baskets"), "editdelete"));
1767 if (deleteChilds
== KMessageBox::No
)
1768 listViewItemForBasket(basket
)->moveChildsBaskets();
1771 doBasketDeletion(basket
);
1773 // basketNumberChanged();
1774 // rebuildBasketsMenu();
1777 void BNPView::doBasketDeletion(Basket
*basket
)
1779 basket
->closeEditor();
1781 QListViewItem
*basketItem
= listViewItemForBasket(basket
);
1782 QListViewItem
*nextOne
;
1783 for (QListViewItem
*child
= basketItem
->firstChild(); child
; child
= nextOne
) {
1784 nextOne
= child
->nextSibling();
1785 // First delete the child baskets:
1786 doBasketDeletion(((BasketListViewItem
*)child
)->basket());
1788 // Then, basket have no child anymore, delete it:
1789 DecoratedBasket
*decoBasket
= basket
->decoration();
1790 basket
->deleteFiles();
1791 removeBasket(basket
);
1792 // Remove the action to avoir keyboard-shortcut clashes:
1793 delete basket
->m_action
; // FIXME: It's quick&dirty. In the future, the Basket should be deleted, and then the KAction deleted in the Basket destructor.
1798 void BNPView::password()
1800 #ifdef HAVE_LIBGPGME
1801 PasswordDlg
dlg(kapp
->activeWindow(), "Password");
1802 Basket
*cur
= currentBasket();
1804 dlg
.setType(cur
->encryptionType());
1805 dlg
.setKey(cur
->encryptionKey());
1807 cur
->setProtection(dlg
.type(), dlg
.key());
1808 if (cur
->encryptionType() != Basket::NoEncryption
)
1814 void BNPView::lockBasket()
1816 #ifdef HAVE_LIBGPGME
1817 Basket
*cur
= currentBasket();
1823 void BNPView::saveAsArchive()
1825 Basket
*basket
= currentBasket();
1829 KConfig
*config
= KGlobal::config();
1830 config
->setGroup("Basket Archive");
1831 QString folder
= config
->readEntry("lastFolder", QDir::homeDirPath()) + "/";
1832 QString url
= folder
+ QString(basket
->basketName()).replace("/", "_") + ".baskets";
1834 QString filter
= "*.baskets|" + i18n("Basket Archives") + "\n*|" + i18n("All Files");
1835 QString destination
= url
;
1836 for (bool askAgain
= true; askAgain
; ) {
1837 destination
= KFileDialog::getSaveFileName(destination
, filter
, this, i18n("Save as Basket Archive"));
1838 if (destination
.isEmpty()) // User canceled
1840 if (dir
.exists(destination
)) {
1841 int result
= KMessageBox::questionYesNoCancel(
1843 "<qt>" + i18n("The file <b>%1</b> already exists. Do you really want to override it?")
1844 .arg(KURL(destination
).fileName()),
1845 i18n("Override File?"),
1846 KGuiItem(i18n("&Override"), "filesave")
1848 if (result
== KMessageBox::Cancel
)
1850 else if (result
== KMessageBox::Yes
)
1855 bool withSubBaskets
= true;//KMessageBox::questionYesNo(this, i18n("Do you want to export sub-baskets too?"), i18n("Save as Basket Archive")) == KMessageBox::Yes;
1857 config
->writeEntry("lastFolder", KURL(destination
).directory());
1860 Archive::save(basket
, withSubBaskets
, destination
);
1863 QString
BNPView::s_fileToOpen
= "";
1865 void BNPView::delayedOpenArchive()
1867 Archive::open(s_fileToOpen
);
1870 void BNPView::openArchive()
1872 QString filter
= "*.baskets|" + i18n("Basket Archives") + "\n*|" + i18n("All Files");
1873 QString path
= KFileDialog::getOpenFileName(QString::null
, filter
, this, i18n("Open Basket Archive"));
1874 if (!path
.isEmpty()) // User has not canceled
1875 Archive::open(path
);
1879 void BNPView::activatedTagShortcut()
1881 Tag
*tag
= Tag::tagForKAction((KAction
*)sender());
1882 currentBasket()->activatedTagShortcut(tag
);
1885 void BNPView::slotBasketNumberChanged(int number
)
1887 m_actPreviousBasket
->setEnabled(number
> 1);
1888 m_actNextBasket
->setEnabled(number
> 1);
1891 void BNPView::slotBasketChanged()
1893 m_actFoldBasket
->setEnabled(canFold());
1894 m_actExpandBasket
->setEnabled(canExpand());
1895 setFiltering(currentBasket() && currentBasket()->decoration()->filterData().isFiltering
);
1898 void BNPView::currentBasketChanged()
1902 void BNPView::isLockedChanged()
1904 bool isLocked
= currentBasket()->isLocked();
1906 setLockStatus(isLocked
);
1908 // m_actLockBasket->setChecked(isLocked);
1909 m_actPropBasket
->setEnabled(!isLocked
);
1910 m_actDelBasket
->setEnabled(!isLocked
);
1911 updateNotesActions();
1914 void BNPView::askNewBasket()
1919 void BNPView::askNewBasket(Basket
*parent
, Basket
*pickProperties
)
1921 NewBasketDefaultProperties properties
;
1922 if (pickProperties
) {
1923 properties
.icon
= pickProperties
->icon();
1924 properties
.backgroundImage
= pickProperties
->backgroundImageName();
1925 properties
.backgroundColor
= pickProperties
->backgroundColorSetting();
1926 properties
.textColor
= pickProperties
->textColorSetting();
1927 properties
.freeLayout
= pickProperties
->isFreeLayout();
1928 properties
.columnCount
= pickProperties
->columnsCount();
1931 NewBasketDialog(parent
, properties
, this).exec();
1934 void BNPView::askNewSubBasket()
1936 askNewBasket( /*parent=*/currentBasket(), /*pickPropertiesOf=*/currentBasket() );
1939 void BNPView::askNewSiblingBasket()
1941 askNewBasket( /*parent=*/parentBasketOf(currentBasket()), /*pickPropertiesOf=*/currentBasket() );
1944 void BNPView::globalPasteInCurrentBasket()
1946 currentBasket()->setInsertPopupMenu();
1947 pasteInCurrentBasket();
1948 currentBasket()->cancelInsertPopupMenu();
1951 void BNPView::pasteInCurrentBasket()
1953 currentBasket()->pasteNote();
1955 if (Settings::usePassivePopup())
1956 showPassiveDropped(i18n("Clipboard content pasted to basket <i>%1</i>"));
1959 void BNPView::pasteSelInCurrentBasket()
1961 currentBasket()->pasteNote(QClipboard::Selection
);
1963 if (Settings::usePassivePopup())
1964 showPassiveDropped(i18n("Selection pasted to basket <i>%1</i>"));
1967 void BNPView::showPassiveDropped(const QString
&title
)
1969 if ( ! currentBasket()->isLocked() ) {
1970 // TODO: Keep basket, so that we show the message only if something was added to a NOT visible basket
1971 m_passiveDroppedTitle
= title
;
1972 m_passiveDroppedSelection
= currentBasket()->selectedNotes();
1973 QTimer::singleShot( c_delayTooltipTime
, this, SLOT(showPassiveDroppedDelayed()) );
1976 showPassiveImpossible(i18n("No note was added."));
1979 void BNPView::showPassiveDroppedDelayed()
1981 if (isMainWindowActive() || m_passiveDroppedSelection
== 0)
1984 QString title
= m_passiveDroppedTitle
;
1986 delete m_passivePopup
; // Delete previous one (if exists): it will then hide it (only one at a time)
1987 m_passivePopup
= new KPassivePopup(Settings::useSystray() ? (QWidget
*)Global::systemTray
: this);
1988 QPixmap contentsPixmap
= NoteDrag::feedbackPixmap(m_passiveDroppedSelection
);
1989 QMimeSourceFactory::defaultFactory()->setPixmap("_passivepopup_image_", contentsPixmap
);
1990 m_passivePopup
->setView(
1991 title
.arg(Tools::textToHTMLWithoutP(currentBasket()->basketName())),
1992 (contentsPixmap
.isNull() ? "" : "<img src=\"_passivepopup_image_\">"),
1993 kapp
->iconLoader()->loadIcon(currentBasket()->icon(), KIcon::NoGroup
, 16, KIcon::DefaultState
, 0L, true));
1994 m_passivePopup
->show();
1997 void BNPView::showPassiveImpossible(const QString
&message
)
1999 delete m_passivePopup
; // Delete previous one (if exists): it will then hide it (only one at a time)
2000 m_passivePopup
= new KPassivePopup(Settings::useSystray() ? (QWidget
*)Global::systemTray
: (QWidget
*)this);
2001 m_passivePopup
->setView(
2002 QString("<font color=red>%1</font>")
2003 .arg(i18n("Basket <i>%1</i> is locked"))
2004 .arg(Tools::textToHTMLWithoutP(currentBasket()->basketName())),
2006 kapp
->iconLoader()->loadIcon(currentBasket()->icon(), KIcon::NoGroup
, 16, KIcon::DefaultState
, 0L, true));
2007 m_passivePopup
->show();
2010 void BNPView::showPassiveContentForced()
2012 showPassiveContent(/*forceShow=*/true);
2015 void BNPView::showPassiveContent(bool forceShow
/* = false*/)
2017 if (!forceShow
&& isMainWindowActive())
2020 // FIXME: Duplicate code (2 times)
2023 delete m_passivePopup
; // Delete previous one (if exists): it will then hide it (only one at a time)
2024 m_passivePopup
= new KPassivePopup(Settings::useSystray() ? (QWidget
*)Global::systemTray
: (QWidget
*)this);
2025 m_passivePopup
->setView(
2026 "<qt>" + kapp
->makeStdCaption( currentBasket()->isLocked()
2027 ? QString("%1 <font color=gray30>%2</font>")
2028 .arg(Tools::textToHTMLWithoutP(currentBasket()->basketName()), i18n("(Locked)"))
2029 : Tools::textToHTMLWithoutP(currentBasket()->basketName()) ),
2031 kapp
->iconLoader()->loadIcon(currentBasket()->icon(), KIcon::NoGroup
, 16, KIcon::DefaultState
, 0L, true));
2032 m_passivePopup
->show();
2035 void BNPView::showPassiveLoading(Basket
*basket
)
2037 if (isMainWindowActive())
2040 delete m_passivePopup
; // Delete previous one (if exists): it will then hide it (only one at a time)
2041 m_passivePopup
= new KPassivePopup(Settings::useSystray() ? (QWidget
*)Global::systemTray
: (QWidget
*)this);
2042 m_passivePopup
->setView(
2043 Tools::textToHTMLWithoutP(basket
->basketName()),
2045 kapp
->iconLoader()->loadIcon(basket
->icon(), KIcon::NoGroup
, 16, KIcon::DefaultState
, 0L, true));
2046 m_passivePopup
->show();
2049 void BNPView::addNoteText() { showMainWindow(); currentBasket()->insertEmptyNote(NoteType::Text
); }
2050 void BNPView::addNoteHtml() { showMainWindow(); currentBasket()->insertEmptyNote(NoteType::Html
); }
2051 void BNPView::addNoteImage() { showMainWindow(); currentBasket()->insertEmptyNote(NoteType::Image
); }
2052 void BNPView::addNoteLink() { showMainWindow(); currentBasket()->insertEmptyNote(NoteType::Link
); }
2053 void BNPView::addNoteColor() { showMainWindow(); currentBasket()->insertEmptyNote(NoteType::Color
); }
2055 void BNPView::aboutToHideNewBasketPopup()
2057 QTimer::singleShot(0, this, SLOT(cancelNewBasketPopup()));
2060 void BNPView::cancelNewBasketPopup()
2062 m_newBasketPopup
= false;
2065 void BNPView::setNewBasketPopup()
2067 m_newBasketPopup
= true;
2070 void BNPView::setCaption(QString s
)
2072 emit
setWindowCaption(s
);
2075 void BNPView::updateStatusBarHint()
2077 m_statusbar
->updateStatusBarHint();
2080 void BNPView::setSelectionStatus(QString s
)
2082 m_statusbar
->setSelectionStatus(s
);
2085 void BNPView::setLockStatus(bool isLocked
)
2087 m_statusbar
->setLockStatus(isLocked
);
2090 void BNPView::postStatusbarMessage(const QString
& msg
)
2092 m_statusbar
->postStatusbarMessage(msg
);
2095 void BNPView::setStatusBarHint(const QString
&hint
)
2097 m_statusbar
->setStatusBarHint(hint
);
2100 void BNPView::setUnsavedStatus(bool isUnsaved
)
2102 m_statusbar
->setUnsavedStatus(isUnsaved
);
2105 void BNPView::setActive(bool active
)
2107 // std::cout << "Main Window Position: setActive(" << (active ? "true" : "false") << ")" << std::endl;
2108 KMainWindow
* win
= Global::mainWindow();
2112 #if KDE_IS_VERSION( 3, 2, 90 ) // KDE 3.3.x
2114 kapp
->updateUserTimestamp(); // If "activate on mouse hovering systray", or "on drag throught systray"
2115 Global::systemTray
->setActive(); // FIXME: add this in the places it need
2117 Global::systemTray
->setInactive();
2118 #elif KDE_IS_VERSION( 3, 1, 90 ) // KDE 3.2.x
2119 // Code from Kopete (that seem to work, in waiting KSystemTray make puplic the toggleSHown) :
2122 //raise() and show() should normaly deIconify the window. but it doesn't do here due
2123 // to a bug in Qt or in KDE (qt3.1.x or KDE 3.1.x) then, i have to call KWin's method
2124 if (win
->isMinimized())
2125 KWin::deIconifyWindow(winId());
2127 if ( ! KWin::windowInfo(winId(), NET::WMDesktop
).onAllDesktops() )
2128 KWin::setOnDesktop(winId(), KWin::currentDesktop());
2130 // Code from me: expected and correct behavviour:
2131 kapp
->updateUserTimestamp(); // If "activate on mouse hovering systray", or "on drag throught systray"
2132 KWin::activateWindow(win
->winId());
2135 #else // KDE 3.1.x and lower
2137 if (win
->isMinimized())
2138 win
->hide(); // If minimized, show() doesn't work !
2139 win
->show(); // Show it
2140 // showNormal(); // If it was minimized
2141 win
->raise(); // Raise it on top
2142 win
->setActiveWindow(); // And set it the active window
2148 void BNPView::hideOnEscape()
2150 if (Settings::useSystray())
2154 bool BNPView::isPart()
2156 return (strcmp(name(), "BNPViewPart") == 0);
2159 bool BNPView::isMainWindowActive()
2161 KMainWindow
* main
= Global::mainWindow();
2162 if (main
&& main
->isActiveWindow())
2167 void BNPView::newBasket()
2172 bool BNPView::createNoteHtml(const QString content
, const QString basket
)
2174 Basket
* b
= basketForFolderName(basket
);
2177 Note
* note
= NoteFactory::createNoteHtml(content
, b
);
2180 b
-> insertCreatedNote(note
);
2184 bool BNPView::changeNoteHtml(const QString content
, const QString basket
, const QString noteName
)
2186 Basket
* b
= basketForFolderName(basket
);
2189 Note
* note
= noteForFileName(noteName
, *b
);
2190 if (!note
|| note
->content()->type()!=NoteType::Html
)
2192 HtmlContent
* noteContent
= (HtmlContent
*)note
->content();
2193 noteContent
->setHtml(content
);
2198 bool BNPView::createNoteFromFile(const QString url
, const QString basket
)
2200 Basket
* b
= basketForFolderName(basket
);
2204 if ( url
.isEmpty() )
2206 Note
* n
= NoteFactory::copyFileAndLoad(kurl
, b
);
2209 b
->insertCreatedNote(n
);
2213 QStringList
BNPView::listBaskets()
2215 QStringList basketList
;
2217 QListViewItemIterator
it(m_tree
);
2218 while (it
.current()) {
2219 BasketListViewItem
*item
= ((BasketListViewItem
*)it
.current());
2220 basketList
.append(item
->basket()->basketName());
2221 basketList
.append(item
->basket()->folderName());
2227 void BNPView::handleCommandLine()
2229 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
2231 /* Custom data folder */
2232 QCString customDataFolder
= args
->getOption("data-folder");
2233 if (customDataFolder
!= 0 && !customDataFolder
.isEmpty())
2235 Global::setCustomSavesFolder(customDataFolder
);
2238 if (args
->isSet("debug")) {
2240 Global::debugWindow
->show();
2243 /* Crash Handler to Mail Developers when Crashing: */
2244 #ifndef BASKET_USE_DRKONQI
2245 if (!args
->isSet("use-drkonquy"))
2246 KCrash::setCrashHandler(Crash::crashHandler
);
2250 void BNPView::reloadBasket(const QString
&folderName
)
2252 basketForFolderName(folderName
)->reload();
2255 /** Scenario of "Hide main window to system tray icon when mouse move out of the window" :
2256 * - At enterEvent() we stop m_tryHideTimer
2257 * - After that and before next, we are SURE cursor is hovering window
2258 * - At leaveEvent() we restart m_tryHideTimer
2259 * - Every 'x' ms, timeoutTryHide() seek if cursor hover a widget of the application or not
2260 * - If yes, we musn't hide the window
2261 * - But if not, we start m_hideTimer to hide main window after a configured elapsed time
2262 * - timeoutTryHide() continue to be called and if cursor move again to one widget of the app, m_hideTimer is stopped
2263 * - If after the configured time cursor hasn't go back to a widget of the application, timeoutHide() is called
2264 * - It then hide the main window to systray icon
2265 * - When the user will show it, enterEvent() will be called the first time he enter mouse to it
2269 /** Why do as this ? Problems with the use of only enterEvent() and leaveEvent() :
2270 * - Resize window or hover titlebar isn't possible : leave/enterEvent
2272 * > Use the grip or Alt+rightDND to resize window
2273 * > Use Alt+DND to move window
2274 * - Each menu trigger the leavEvent
2277 void BNPView::enterEvent(QEvent
*)
2280 m_tryHideTimer
->stop();
2282 m_hideTimer
->stop();
2285 void BNPView::leaveEvent(QEvent
*)
2287 if (Settings::useSystray() && Settings::hideOnMouseOut() && m_tryHideTimer
)
2288 m_tryHideTimer
->start(50);
2291 void BNPView::timeoutTryHide()
2293 // If a menu is displayed, do nothing for the moment
2294 if (kapp
->activePopupWidget() != 0L)
2297 if (kapp
->widgetAt(QCursor::pos()) != 0L)
2298 m_hideTimer
->stop();
2299 else if ( ! m_hideTimer
->isActive() ) // Start only one time
2300 m_hideTimer
->start(Settings::timeToHideOnMouseOut() * 100, true);
2302 // If a sub-dialog is oppened, we musn't hide the main window:
2303 if (kapp
->activeWindow() != 0L && kapp
->activeWindow() != Global::mainWindow())
2304 m_hideTimer
->stop();
2307 void BNPView::timeoutHide()
2309 // We check that because the setting can have been set to off
2310 if (Settings::useSystray() && Settings::hideOnMouseOut())
2312 m_tryHideTimer
->stop();
2315 void BNPView::changedSelectedNotes()
2317 // tabChanged(0); // FIXME: NOT OPTIMIZED
2320 /*void BNPView::areSelectedNotesCheckedChanged(bool checked)
2322 m_actCheckNotes->setChecked(checked && currentBasket()->showCheckBoxes());
2325 void BNPView::enableActions()
2327 Basket
*basket
= currentBasket();
2331 m_actLockBasket
->setEnabled(!basket
->isLocked() && basket
->isEncrypted());
2333 m_actPassBasket
->setEnabled(!basket
->isLocked());
2334 m_actPropBasket
->setEnabled(!basket
->isLocked());
2335 m_actDelBasket
->setEnabled(!basket
->isLocked());
2336 m_actExportToHtml
->setEnabled(!basket
->isLocked());
2337 m_actShowFilter
->setEnabled(!basket
->isLocked());
2338 m_actFilterAllBaskets
->setEnabled(!basket
->isLocked());
2339 m_actResetFilter
->setEnabled(!basket
->isLocked());
2340 basket
->decoration()->filterBar()->setEnabled(!basket
->isLocked());
2343 void BNPView::showMainWindow()
2345 KMainWindow
*win
= Global::mainWindow();
2355 void BNPView::populateTagsMenu()
2357 KPopupMenu
*menu
= (KPopupMenu
*)(popupMenu("tags"));
2358 if (menu
== 0 || currentBasket() == 0) // TODO: Display a messagebox. [menu is 0, surely because on first launch, the XMLGUI does not work!]
2362 Note
*referenceNote
;
2363 if (currentBasket()->focusedNote() && currentBasket()->focusedNote()->isSelected())
2364 referenceNote
= currentBasket()->focusedNote();
2366 referenceNote
= currentBasket()->firstSelected();
2368 populateTagsMenu(*menu
, referenceNote
);
2370 m_lastOpenedTagsMenu
= menu
;
2371 // connect( menu, SIGNAL(aboutToHide()), this, SLOT(disconnectTagsMenu()) );
2374 void BNPView::populateTagsMenu(KPopupMenu
&menu
, Note
*referenceNote
)
2376 if (currentBasket() == 0)
2379 currentBasket()->m_tagPopupNote
= referenceNote
;
2380 bool enable
= currentBasket()->countSelecteds() > 0;
2382 QValueList
<Tag
*>::iterator it
;
2384 State
*currentState
;
2386 for (it
= Tag::all
.begin(); it
!= Tag::all
.end(); ++it
) {
2387 // Current tag and first state of it:
2389 currentState
= currentTag
->states().first();
2390 QKeySequence sequence
;
2391 if (!currentTag
->shortcut().isNull())
2392 sequence
= currentTag
->shortcut().operator QKeySequence();
2393 menu
.insertItem(StateMenuItem::checkBoxIconSet(
2394 (referenceNote
? referenceNote
->hasTag(currentTag
) : false),
2396 new StateMenuItem(currentState
, sequence
, true),
2399 if (!currentTag
->shortcut().isNull())
2400 menu
.setAccel(sequence
, i
);
2401 menu
.setItemEnabled(i
, enable
);
2405 menu
.insertSeparator();
2406 // menu.insertItem( /*SmallIconSet("editdelete"),*/ "&Assign new Tag...", 1 );
2407 //id = menu.insertItem( SmallIconSet("editdelete"), "&Remove All", -2 );
2408 //if (referenceNote->states().isEmpty())
2409 // menu.setItemEnabled(id, false);
2410 // menu.insertItem( SmallIconSet("configure"), "&Customize...", 3 );
2411 menu
.insertItem( new IndentedMenuItem(i18n("&Assign new Tag...")), 1 );
2412 menu
.insertItem( new IndentedMenuItem(i18n("&Remove All"), "editdelete"), 2 );
2413 menu
.insertItem( new IndentedMenuItem(i18n("&Customize..."), "configure"), 3 );
2415 menu
.setItemEnabled(1, enable
);
2416 if (!currentBasket()->selectedNotesHaveTags())
2417 menu
.setItemEnabled(2, false);
2419 connect( &menu
, SIGNAL(activated(int)), currentBasket(), SLOT(toggledTagInMenu(int)) );
2420 connect( &menu
, SIGNAL(aboutToHide()), currentBasket(), SLOT(unlockHovering()) );
2421 connect( &menu
, SIGNAL(aboutToHide()), currentBasket(), SLOT(disableNextClick()) );
2424 void BNPView::connectTagsMenu()
2426 connect( popupMenu("tags"), SIGNAL(aboutToShow()), this, SLOT(populateTagsMenu()) );
2427 connect( popupMenu("tags"), SIGNAL(aboutToHide()), this, SLOT(disconnectTagsMenu()) );
2431 * The Tags menu is ONLY created once the BasKet KPart is first shown.
2432 * So we can use this menu only from then?
2433 * When the KPart is changed in Kontact, and then the BasKet KPart is shown again,
2434 * Kontact created a NEW Tags menu. So we should connect again.
2435 * But when Kontact main window is hidden and then re-shown, the menu does not change.
2436 * So we disconnect at hide event to ensure only one connection: the next show event will not connects another time.
2439 void BNPView::showEvent(QShowEvent
*)
2442 QTimer::singleShot( 0, this, SLOT(connectTagsMenu()) );
2445 m_firstShow
= false;
2448 if (isPart()/*TODO: && !LikeBack::enabledBar()*/) {
2449 Global::likeBack
->enableBar();
2453 void BNPView::hideEvent(QHideEvent
*)
2456 disconnect( popupMenu("tags"), SIGNAL(aboutToShow()), this, SLOT(populateTagsMenu()) );
2457 disconnect( popupMenu("tags"), SIGNAL(aboutToHide()), this, SLOT(disconnectTagsMenu()) );
2461 Global::likeBack
->disableBar();
2464 void BNPView::disconnectTagsMenu()
2466 QTimer::singleShot( 0, this, SLOT(disconnectTagsMenuDelayed()) );
2469 void BNPView::disconnectTagsMenuDelayed()
2471 disconnect( m_lastOpenedTagsMenu
, SIGNAL(activated(int)), currentBasket(), SLOT(toggledTagInMenu(int)) );
2472 disconnect( m_lastOpenedTagsMenu
, SIGNAL(aboutToHide()), currentBasket(), SLOT(unlockHovering()) );
2473 disconnect( m_lastOpenedTagsMenu
, SIGNAL(aboutToHide()), currentBasket(), SLOT(disableNextClick()) );
2476 void BNPView::showGlobalShortcutsSettingsDialog()
2478 KKeyDialog::configure(Global::globalAccel
);
2480 Global::globalAccel
->writeSettings();
2483 #include "bnpview.moc"