TDE personal information management applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1443 lines
44 KiB

  1. /*******************************************************************
  2. KNotes -- Notes for the KDE project
  3. Copyright (c) 1997-2006, The KNotes Developers
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  15. *******************************************************************/
  16. #include <tqlabel.h>
  17. #include <tqdrawutil.h>
  18. #include <tqsize.h>
  19. #include <tqsizegrip.h>
  20. #include <tqbitmap.h>
  21. #include <tqcursor.h>
  22. #include <tqpainter.h>
  23. #include <tqpaintdevicemetrics.h>
  24. #include <tqsimplerichtext.h>
  25. #include <tqobjectlist.h>
  26. #include <tqfile.h>
  27. #include <tqcheckbox.h>
  28. #include <tqtimer.h>
  29. #include <tdeapplication.h>
  30. #include <kdebug.h>
  31. #include <tdeaction.h>
  32. #include <kstdaction.h>
  33. #include <kcombobox.h>
  34. #include <tdetoolbar.h>
  35. #include <tdepopupmenu.h>
  36. #include <kxmlguibuilder.h>
  37. #include <kxmlguifactory.h>
  38. #include <kcolordrag.h>
  39. #include <kiconeffect.h>
  40. #include <tdelocale.h>
  41. #include <kstandarddirs.h>
  42. #include <tdemessagebox.h>
  43. #include <kfind.h>
  44. #include <kprocess.h>
  45. #include <kinputdialog.h>
  46. #include <kmdcodec.h>
  47. #include <tdeglobalsettings.h>
  48. #include <tdefiledialog.h>
  49. #include <tdeio/netaccess.h>
  50. #include <libkcal/journal.h>
  51. #include "knote.h"
  52. #include "knotebutton.h"
  53. #include "knoteedit.h"
  54. #include "knoteconfig.h"
  55. #include "knotesglobalconfig.h"
  56. #include "knoteconfigdlg.h"
  57. #include "knotealarmdlg.h"
  58. #include "knotehostdlg.h"
  59. #include "knotesnetsend.h"
  60. #include "knoteprinter.h"
  61. #include "version.h"
  62. #include "pushpin.xpm"
  63. #include <twin.h>
  64. #include <netwm.h>
  65. #include <fixx11h.h>
  66. using namespace KCal;
  67. int KNote::s_ppOffset = 0;
  68. KNote::KNote( TQDomDocument buildDoc, Journal *j, TQWidget *parent, const char *name )
  69. : TQFrame( parent, name, WStyle_Customize | WStyle_NoBorder | WDestructiveClose ),
  70. m_label( 0 ), m_pushpin( 0 ), m_fold( 0 ), m_button( 0 ), m_tool( 0 ), m_editor( 0 ),
  71. m_config( 0 ), m_journal( j ), m_find( 0 ),
  72. m_twinConf( TDESharedConfig::openConfig( "twinrc", true ) ),
  73. m_busy( 0 ), m_deleteWhenIdle( false ), m_blockEmitDataChanged( false )
  74. {
  75. setAcceptDrops( true );
  76. actionCollection()->setWidget( this );
  77. setDOMDocument( buildDoc );
  78. // just set the name of the file to save the actions to, do NOT reparse it
  79. setXMLFile( instance()->instanceName() + "ui.rc", false, false );
  80. // if there is no title yet, use the start date if valid
  81. // (KOrganizer's journals don't have titles but a valid start date)
  82. if ( m_journal->summary().isNull() && m_journal->dtStart().isValid() )
  83. {
  84. TQString s = TDEGlobal::locale()->formatDateTime( m_journal->dtStart() );
  85. m_journal->setSummary( s );
  86. }
  87. // create the menu items for the note - not the editor...
  88. // rename, mail, print, save as, insert date, alarm, close, delete, new note
  89. new TDEAction( i18n("New"), "document-new", 0,
  90. TQT_TQOBJECT(this),TQT_SLOT(slotRequestNewNote()) , actionCollection(), "new_note" );
  91. new TDEAction( i18n("Rename..."), "text", 0,
  92. TQT_TQOBJECT(this), TQT_SLOT(slotRename()), actionCollection(), "rename_note" );
  93. m_readOnly = new TDEToggleAction( i18n("Lock"), "system-lock-screen" , 0,
  94. TQT_TQOBJECT(this), TQT_SLOT(slotUpdateReadOnly()), actionCollection(), "lock_note" );
  95. m_readOnly->setCheckedState( KGuiItem( i18n("Unlock"), "unlock" ) );
  96. new TDEAction( i18n("Hide"), "window-close" , Key_Escape,
  97. TQT_TQOBJECT(this), TQT_SLOT(slotClose()), actionCollection(), "hide_note" );
  98. new TDEAction( i18n("Delete"), "knotes_delete", 0,
  99. TQT_TQOBJECT(this), TQT_SLOT(slotKill()), actionCollection(), "delete_note" );
  100. new TDEAction( i18n("Insert Date"), "knotes_date", 0 ,
  101. TQT_TQOBJECT(this), TQT_SLOT(slotInsDate()), actionCollection(), "insert_date" );
  102. new TDEAction( i18n("Set Alarm..."), "knotes_alarm", 0 ,
  103. TQT_TQOBJECT(this), TQT_SLOT(slotSetAlarm()), actionCollection(), "set_alarm" );
  104. new TDEAction( i18n("Send..."), "network", 0,
  105. TQT_TQOBJECT(this), TQT_SLOT(slotSend()), actionCollection(), "send_note" );
  106. new TDEAction( i18n("Mail..."), "mail-send", 0,
  107. TQT_TQOBJECT(this), TQT_SLOT(slotMail()), actionCollection(), "mail_note" );
  108. new TDEAction( i18n("Save As..."), "document-save-as", 0,
  109. TQT_TQOBJECT(this), TQT_SLOT(slotSaveAs()), actionCollection(), "save_note" );
  110. KStdAction::print( TQT_TQOBJECT(this), TQT_SLOT(slotPrint()), actionCollection(), "print_note" );
  111. new TDEAction( i18n("Preferences..."), "configure", 0,
  112. TQT_TQOBJECT(this), TQT_SLOT(slotPreferences()), actionCollection(), "configure_note" );
  113. m_keepAbove = new TDEToggleAction( i18n("Keep Above Others"), "go-up", 0,
  114. TQT_TQOBJECT(this), TQT_SLOT(slotUpdateKeepAboveBelow()), actionCollection(), "keep_above" );
  115. m_keepAbove->setExclusiveGroup( "keepAB" );
  116. m_keepBelow = new TDEToggleAction( i18n("Keep Below Others"), "go-down", 0,
  117. TQT_TQOBJECT(this), TQT_SLOT(slotUpdateKeepAboveBelow()), actionCollection(), "keep_below" );
  118. m_keepBelow->setExclusiveGroup( "keepAB" );
  119. m_toDesktop = new TDEListAction( i18n("To Desktop"), 0,
  120. TQT_TQOBJECT(this), TQT_SLOT(slotPopupActionToDesktop(int)), actionCollection(), "to_desktop" );
  121. connect( m_toDesktop->popupMenu(), TQT_SIGNAL(aboutToShow()), TQT_TQOBJECT(this), TQT_SLOT(slotUpdateDesktopActions()) );
  122. // invisible action to walk through the notes to make this configurable
  123. new TDEAction( i18n("Walk Through Notes"), 0, SHIFT+Key_BackTab,
  124. TQT_TQOBJECT(this), TQT_SIGNAL(sigShowNextNote()), actionCollection(), "walk_notes" );
  125. // create the note header, button and label...
  126. m_label = new TQLabel( this );
  127. m_label->setFrameStyle( NoFrame );
  128. m_label->setLineWidth( 0 );
  129. m_label->installEventFilter( this ); // receive events (for dragging & action menu)
  130. setName( m_journal->summary() ); // don't worry, no signals are connected at this stage yet
  131. m_button = new KNoteButton( "knotes_close", this );
  132. connect( m_button, TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), TQT_SLOT(slotClose()) );
  133. // create the note editor
  134. m_editor = new KNoteEdit( actionCollection(), this );
  135. m_editor->setNote( this );
  136. m_editor->installEventFilter( this ); // receive events (for modified)
  137. m_editor->viewport()->installEventFilter( this );
  138. connect( m_editor, TQT_SIGNAL(contentsMoving( int, int )), TQT_TQOBJECT(this), TQT_SLOT(slotUpdateViewport( int, int )));
  139. KXMLGUIBuilder builder( this );
  140. KXMLGUIFactory factory( &builder, TQT_TQOBJECT(this) );
  141. factory.addClient( this );
  142. m_menu = dynamic_cast<TDEPopupMenu*>(factory.container( "note_context", this ));
  143. m_edit_menu = dynamic_cast<TDEPopupMenu*>(factory.container( "note_edit", this ));
  144. m_tool = dynamic_cast<TDEToolBar*>(factory.container( "note_tool", this ));
  145. if ( m_tool ) {
  146. m_tool->setIconSize( 10 );
  147. m_tool->setFixedHeight( 16 );
  148. m_tool->setIconText( TDEToolBar::IconOnly );
  149. // if there was just a way of making KComboBox adhere the toolbar height...
  150. TQObjectList *list = m_tool->queryList( "KComboBox" );
  151. TQObjectListIt it( *list );
  152. while ( it.current() != 0 )
  153. {
  154. KComboBox *combo = (KComboBox *)it.current();
  155. TQFont font = combo->font();
  156. font.setPointSize( 7 );
  157. combo->setFont( font );
  158. combo->setFixedHeight( 14 );
  159. ++it;
  160. }
  161. delete list;
  162. m_tool->hide();
  163. }
  164. setFocusProxy( m_editor );
  165. // create the resize handle
  166. m_editor->setCornerWidget( new TQSizeGrip( this ) );
  167. uint width = m_editor->cornerWidget()->width();
  168. uint height = m_editor->cornerWidget()->height();
  169. TQBitmap mask;
  170. mask.resize( width, height );
  171. mask.fill( color0 );
  172. TQPointArray array;
  173. array.setPoints( 3, 0, height, width, height, width, 0 );
  174. TQPainter p;
  175. p.begin( &mask );
  176. p.setBrush( color1 );
  177. p.drawPolygon( array );
  178. p.end();
  179. m_editor->cornerWidget()->setMask( mask );
  180. m_editor->cornerWidget()->setBackgroundMode( PaletteBase );
  181. // the config file location
  182. TQString configFile = TDEGlobal::dirs()->saveLocation( "appdata", "notes/" );
  183. configFile += m_journal->uid();
  184. // no config file yet? -> use the default display config if available
  185. // we want to write to configFile, so use "false"
  186. bool newNote = !TDEIO::NetAccess::exists( KURL::fromPathOrURL( configFile ), false, 0 );
  187. m_config = new KNoteConfig( TDESharedConfig::openConfig( configFile, false, false ) );
  188. m_config->readConfig();
  189. m_config->setVersion( KNOTES_VERSION );
  190. if ( newNote )
  191. {
  192. // until tdelibs provides copying of TDEConfigSkeletons (KDE 3.4)
  193. KNotesGlobalConfig *globalConfig = KNotesGlobalConfig::self();
  194. m_config->setBgColor( globalConfig->bgColor() );
  195. m_config->setFgColor( globalConfig->fgColor() );
  196. m_config->setWidth( globalConfig->width() );
  197. m_config->setHeight( globalConfig->height() );
  198. m_config->setFont( globalConfig->font() );
  199. m_config->setTitleFont( globalConfig->titleFont() );
  200. m_config->setAutoIndent( globalConfig->autoIndent() );
  201. m_config->setRichText( globalConfig->richText() );
  202. m_config->setTabSize( globalConfig->tabSize() );
  203. m_config->setReadOnly( globalConfig->readOnly() );
  204. m_config->setDesktop( globalConfig->desktop() );
  205. m_config->setHideNote( globalConfig->hideNote() );
  206. m_config->setPosition( globalConfig->position() );
  207. m_config->setShowInTaskbar( globalConfig->showInTaskbar() );
  208. m_config->setKeepAbove( globalConfig->keepAbove() );
  209. m_config->setKeepBelow( globalConfig->keepBelow() );
  210. m_config->writeConfig();
  211. }
  212. // set up the look&feel of the note
  213. setMinimumSize( 20, 20 );
  214. setLineWidth( 1 );
  215. setMargin( 0 );
  216. m_editor->setMargin( 0 );
  217. m_editor->setFrameStyle( NoFrame );
  218. m_editor->setBackgroundOrigin( WindowOrigin );
  219. // can be done here since this doesn't pick up changes while KNotes is running anyway
  220. bool closeLeft = false;
  221. m_twinConf->setGroup( "Style" );
  222. if ( m_twinConf->readBoolEntry( "CustomButtonPositions" ) )
  223. closeLeft = m_twinConf->readEntry( "ButtonsOnLeft" ).find( 'X' ) > -1;
  224. TQPixmap pushpin_pix;
  225. if ( closeLeft )
  226. pushpin_pix = TQPixmap( TQPixmap( pushpin_xpm ).convertToImage().mirror( true, false ) );
  227. else
  228. pushpin_pix = TQPixmap( pushpin_xpm );
  229. // the pushpin label at the top left or right corner
  230. m_pushpin = new TQLabel( this );
  231. m_pushpin->setScaledContents( true );
  232. m_pushpin->setBackgroundMode( NoBackground );
  233. m_pushpin->setPixmap( pushpin_pix );
  234. m_pushpin->resize( pushpin_pix.size() );
  235. // fold label at bottom right corner
  236. m_fold = new TQLabel( this );
  237. m_fold->setScaledContents( true );
  238. m_fold->setBackgroundMode( NoBackground );
  239. // load the display configuration of the note
  240. width = m_config->width();
  241. height = m_config->height();
  242. resize( width, height );
  243. // let KWin do the placement if the position is illegal--at least 10 pixels
  244. // of a note need to be visible
  245. const TQPoint& position = m_config->position();
  246. TQRect desk = kapp->desktop()->rect();
  247. desk.addCoords( 10, 10, -10, -10 );
  248. if ( desk.intersects( TQRect( position, TQSize( width, height ) ) ) )
  249. move( position ); // do before calling show() to avoid flicker
  250. // config items in the journal have priority
  251. TQString property = m_journal->customProperty( "KNotes", "FgColor" );
  252. if ( !property.isNull() )
  253. m_config->setFgColor( TQColor( property ) );
  254. else
  255. m_journal->setCustomProperty( "KNotes", "FgColor", m_config->fgColor().name() );
  256. property = m_journal->customProperty( "KNotes", "BgColor" );
  257. if ( !property.isNull() )
  258. m_config->setBgColor( TQColor( property ) );
  259. else
  260. m_journal->setCustomProperty( "KNotes", "BgColor", m_config->bgColor().name() );
  261. property = m_journal->customProperty( "KNotes", "RichText" );
  262. if ( !property.isNull() )
  263. m_config->setRichText( property == "true" ? true : false );
  264. else
  265. m_journal->setCustomProperty( "KNotes", "RichText", m_config->richText() ? "true" : "false" );
  266. // read configuration settings...
  267. slotApplyConfig();
  268. // create the mask for the fold---to be done after slotApplyConfig(),
  269. // which calls createFold()
  270. m_fold->setMask( TQRegion( m_fold->pixmap()->createHeuristicMask() ) );
  271. // if this is a new note put on current desktop - we can't use defaults
  272. // in TDEConfig XT since only _changes_ will be stored in the config file
  273. int desktop = m_config->desktop();
  274. if ( desktop < 0 && desktop != NETWinInfo::OnAllDesktops )
  275. desktop = KWin::currentDesktop();
  276. // show the note if desired
  277. if ( desktop != 0 && !m_config->hideNote() )
  278. {
  279. // to avoid flicker, call this before show()
  280. toDesktop( desktop );
  281. show();
  282. // because KWin forgets about that for hidden windows
  283. if ( desktop == NETWinInfo::OnAllDesktops )
  284. toDesktop( desktop );
  285. }
  286. m_editor->setText( m_journal->description() );
  287. m_editor->setModified( false );
  288. m_readOnly->setChecked( m_config->readOnly() );
  289. slotUpdateReadOnly();
  290. if ( m_config->keepAbove() )
  291. m_keepAbove->setChecked( true );
  292. else if ( m_config->keepBelow() )
  293. m_keepBelow->setChecked( true );
  294. else
  295. {
  296. m_keepAbove->setChecked( false );
  297. m_keepBelow->setChecked( false );
  298. }
  299. slotUpdateKeepAboveBelow();
  300. // HACK: update the icon color - again after showing the note, to make kicker aware of the new colors
  301. TDEIconEffect effect;
  302. TQPixmap icon = effect.apply( kapp->icon(), TDEIconEffect::Colorize, 1, m_config->bgColor(), false );
  303. TQPixmap miniIcon = effect.apply( kapp->miniIcon(), TDEIconEffect::Colorize, 1, m_config->bgColor(), false );
  304. KWin::setIcons( winId(), icon, miniIcon );
  305. }
  306. KNote::~KNote()
  307. {
  308. delete m_config;
  309. }
  310. void KNote::slotRequestNewNote()
  311. {
  312. //Be sure to save before to request a new note
  313. saveConfig();
  314. saveData();
  315. emit sigRequestNewNote();
  316. }
  317. void KNote::changeJournal(KCal::Journal *journal)
  318. {
  319. m_journal = journal;
  320. m_editor->setText( m_journal->description() );
  321. m_label->setText( m_journal->summary() );
  322. updateLabelAlignment();
  323. }
  324. // -------------------- public slots -------------------- //
  325. void KNote::slotKill( bool force )
  326. {
  327. m_blockEmitDataChanged = true;
  328. if ( !force &&
  329. KMessageBox::warningContinueCancel( this,
  330. i18n("<qt>Do you really want to delete note <b>%1</b>?</qt>").arg( m_label->text() ),
  331. i18n("Confirm Delete"), KGuiItem( i18n("&Delete"), "edit-delete" ),
  332. "ConfirmDeleteNote"
  333. )
  334. != KMessageBox::Continue )
  335. {
  336. m_blockEmitDataChanged = false;
  337. return;
  338. }
  339. aboutToEnterEventLoop();
  340. // delete the configuration first, then the corresponding file
  341. delete m_config;
  342. m_config = 0;
  343. TQString configFile = TDEGlobal::dirs()->saveLocation( "appdata", "notes/" );
  344. configFile += m_journal->uid();
  345. if ( !TDEIO::NetAccess::del( KURL::fromPathOrURL( configFile ), this ) )
  346. kdError(5500) << "Can't remove the note config: " << configFile << endl;
  347. emit sigKillNote( m_journal );
  348. eventLoopLeft();
  349. }
  350. // -------------------- public member functions -------------------- //
  351. void KNote::saveData(bool update)
  352. {
  353. m_journal->setSummary( m_label->text() );
  354. m_journal->setDescription( m_editor->text() );
  355. m_journal->setCustomProperty( "KNotes", "FgColor", m_config->fgColor().name() );
  356. m_journal->setCustomProperty( "KNotes", "BgColor", m_config->bgColor().name() );
  357. m_journal->setCustomProperty( "KNotes", "RichText", m_config->richText() ? "true" : "false" );
  358. if(update) {
  359. emit sigDataChanged( noteId() );
  360. m_editor->setModified( false );
  361. }
  362. }
  363. void KNote::saveConfig() const
  364. {
  365. m_config->setWidth( width() );
  366. m_config->setHeight( height() );
  367. m_config->setPosition( pos() );
  368. NETWinInfo wm_client( tqt_xdisplay(), winId(), tqt_xrootwin(), NET::WMDesktop );
  369. if ( wm_client.desktop() == NETWinInfo::OnAllDesktops || wm_client.desktop() > 0 )
  370. m_config->setDesktop( wm_client.desktop() );
  371. // actually store the config on disk
  372. m_config->writeConfig();
  373. }
  374. TQString KNote::noteId() const
  375. {
  376. return m_journal->uid();
  377. }
  378. TQDateTime KNote::getLastModified() const
  379. {
  380. return m_journal->lastModified();
  381. }
  382. TQString KNote::name() const
  383. {
  384. return m_label->text();
  385. }
  386. TQString KNote::text() const
  387. {
  388. return m_editor->text();
  389. }
  390. TQString KNote::plainText() const
  391. {
  392. if ( m_editor->textFormat() == RichText )
  393. {
  394. TQTextEdit conv;
  395. conv.setTextFormat( RichText );
  396. conv.setText( m_editor->text() );
  397. conv.setTextFormat( PlainText );
  398. return conv.text();
  399. }
  400. else
  401. return m_editor->text();
  402. }
  403. void KNote::setName( const TQString& name )
  404. {
  405. m_label->setText( name );
  406. updateLabelAlignment();
  407. if ( m_editor ) // not called from CTOR?
  408. saveData();
  409. // set the window's name for the taskbar entry to be more helpful (#58338)
  410. NETWinInfo note_win( tqt_xdisplay(), winId(), tqt_xrootwin(), NET::WMDesktop );
  411. note_win.setName( name.utf8() );
  412. emit sigNameChanged();
  413. }
  414. void KNote::setText( const TQString& text )
  415. {
  416. m_editor->setText( text );
  417. saveData();
  418. }
  419. TQColor KNote::fgColor() const
  420. {
  421. return m_config->fgColor();
  422. }
  423. TQColor KNote::bgColor() const
  424. {
  425. return m_config->bgColor();
  426. }
  427. void KNote::setColor( const TQColor& fg, const TQColor& bg )
  428. {
  429. bool updateJournal = false;
  430. TQString journalFg = m_journal->customProperty( "KNotes", "FgColor" );
  431. if ( journalFg.isEmpty() || journalFg != fg.name() )
  432. {
  433. m_journal->setCustomProperty( "KNotes", "FgColor", fg.name() );
  434. updateJournal = true;
  435. }
  436. TQString journalbg = m_journal->customProperty( "KNotes", "BgColor" );
  437. if ( journalbg.isEmpty() || journalbg != bg.name() )
  438. {
  439. m_journal->setCustomProperty( "KNotes", "BgColor", bg.name() );
  440. updateJournal = true;
  441. }
  442. m_config->setFgColor( fg );
  443. m_config->setBgColor( bg );
  444. if (updateJournal)
  445. {
  446. // Only update the journal if new configuration was really used.
  447. // This is necessary because setColor() is called also when loading a note from an .ics
  448. // file and we do not want to inadvertantly update the last modified field each time.
  449. m_journal->updated(); // because setCustomProperty() doesn't call it!!
  450. emit sigDataChanged(noteId());
  451. }
  452. m_config->writeConfig();
  453. TQPalette newpalette = palette();
  454. newpalette.setColor( TQColorGroup::Background, bg );
  455. newpalette.setColor( TQColorGroup::Foreground, fg );
  456. newpalette.setColor( TQColorGroup::Base, bg ); // text background
  457. newpalette.setColor( TQColorGroup::Text, fg ); // text color
  458. newpalette.setColor( TQColorGroup::Button, bg );
  459. newpalette.setColor( TQColorGroup::ButtonText, fg );
  460. // newpalette.setColor( TQColorGroup::Highlight, bg );
  461. // newpalette.setColor( TQColorGroup::HighlightedText, fg );
  462. // the shadow
  463. newpalette.setColor( TQColorGroup::Midlight, bg.light(150) );
  464. newpalette.setColor( TQColorGroup::Shadow, bg.dark(116) );
  465. newpalette.setColor( TQColorGroup::Light, bg.light(180) );
  466. if ( s_ppOffset )
  467. newpalette.setColor( TQColorGroup::Dark, bg.dark(200) );
  468. else
  469. newpalette.setColor( TQColorGroup::Dark, bg.dark(108) );
  470. setPalette( newpalette );
  471. // set the text color
  472. m_editor->setTextColor( fg );
  473. // set the background color or gradient
  474. updateBackground();
  475. // set darker value for the hide button...
  476. TQPalette darker = palette();
  477. darker.setColor( TQColorGroup::Button, bg.dark(116) );
  478. m_button->setPalette( darker );
  479. // update the icon color
  480. TDEIconEffect effect;
  481. TQPixmap icon = effect.apply( kapp->icon(), TDEIconEffect::Colorize, 1, bg, false );
  482. TQPixmap miniIcon = effect.apply( kapp->miniIcon(), TDEIconEffect::Colorize, 1, bg, false );
  483. KWin::setIcons( winId(), icon, miniIcon );
  484. // set the color for the selection used to highlight the find stuff
  485. TQColor sel = palette().color( TQPalette::Active, TQColorGroup::Base ).dark();
  486. if ( sel == TQt::black )
  487. sel = palette().color( TQPalette::Active, TQColorGroup::Base ).light();
  488. m_editor->setSelectionAttributes( 1, sel, true );
  489. // update the color of the fold
  490. createFold();
  491. // update the color of the title
  492. updateFocus();
  493. emit sigColorChanged();
  494. }
  495. void KNote::find( const TQString& pattern, long options )
  496. {
  497. delete m_find;
  498. m_find = new KFind( pattern, options, this );
  499. connect( m_find, TQT_SIGNAL(highlight( const TQString &, int, int )),
  500. TQT_TQOBJECT(this), TQT_SLOT(slotHighlight( const TQString &, int, int )) );
  501. connect( m_find, TQT_SIGNAL(findNext()), TQT_TQOBJECT(this), TQT_SLOT(slotFindNext()) );
  502. m_find->setData( plainText() );
  503. slotFindNext();
  504. }
  505. void KNote::slotFindNext()
  506. {
  507. // TODO: honor FindBackwards
  508. // TODO: dialogClosed() -> delete m_find
  509. // Let KFind inspect the text fragment, and display a dialog if a match is found
  510. KFind::Result res = m_find->find();
  511. if ( res == KFind::NoMatch ) // i.e. at end-pos
  512. {
  513. m_editor->removeSelection( 1 );
  514. emit sigFindFinished();
  515. delete m_find;
  516. m_find = 0;
  517. }
  518. else
  519. {
  520. show();
  521. KWin::setCurrentDesktop( KWin::windowInfo( winId() ).desktop() );
  522. }
  523. }
  524. void KNote::slotHighlight( const TQString& str, int idx, int len )
  525. {
  526. int paraFrom = 0, idxFrom = 0, p = 0;
  527. for ( ; p < idx; ++p )
  528. if ( str[p] == '\n' )
  529. {
  530. ++paraFrom;
  531. idxFrom = 0;
  532. }
  533. else
  534. ++idxFrom;
  535. int paraTo = paraFrom, idxTo = idxFrom;
  536. for ( ; p < idx + len; ++p )
  537. {
  538. if ( str[p] == '\n' )
  539. {
  540. ++paraTo;
  541. idxTo = 0;
  542. }
  543. else
  544. ++idxTo;
  545. }
  546. m_editor->setSelection( paraFrom, idxFrom, paraTo, idxTo, 1 );
  547. }
  548. bool KNote::isModified() const
  549. {
  550. return m_editor->isModified();
  551. }
  552. // FIXME KDE 4.0: remove sync(), isNew() and isModified()
  553. void KNote::sync( const TQString& app )
  554. {
  555. TQByteArray sep( 1 );
  556. sep[0] = '\0';
  557. KMD5 hash;
  558. TQCString result;
  559. hash.update( m_label->text().utf8() );
  560. hash.update( sep );
  561. hash.update( m_editor->text().utf8() );
  562. hash.hexDigest( result );
  563. // hacky... not possible with TDEConfig XT
  564. TDEConfig *config = m_config->config();
  565. config->setGroup( "Synchronisation" );
  566. config->writeEntry( app, result.data() );
  567. }
  568. bool KNote::isNew( const TQString& app ) const
  569. {
  570. TDEConfig *config = m_config->config();
  571. config->setGroup( "Synchronisation" );
  572. TQString hash = config->readEntry( app );
  573. return hash.isEmpty();
  574. }
  575. bool KNote::isModified( const TQString& app ) const
  576. {
  577. TQByteArray sep( 1 );
  578. sep[0] = '\0';
  579. KMD5 hash;
  580. hash.update( m_label->text().utf8() );
  581. hash.update( sep );
  582. hash.update( m_editor->text().utf8() );
  583. hash.hexDigest();
  584. TDEConfig *config = m_config->config();
  585. config->setGroup( "Synchronisation" );
  586. TQString orig = config->readEntry( app );
  587. if ( hash.verify( orig.utf8() ) ) // returns false on error!
  588. return false;
  589. else
  590. return true;
  591. }
  592. void KNote::setStyle( int style )
  593. {
  594. if ( style == KNotesGlobalConfig::EnumStyle::Plain )
  595. s_ppOffset = 0;
  596. else
  597. s_ppOffset = 12;
  598. }
  599. // ------------------ private slots (menu actions) ------------------ //
  600. void KNote::slotRename()
  601. {
  602. m_blockEmitDataChanged = true;
  603. // pop up dialog to get the new name
  604. bool ok;
  605. aboutToEnterEventLoop();
  606. TQString oldName = m_label->text();
  607. TQString newName = KInputDialog::getText( TQString(),
  608. i18n("Please enter the new name:"), m_label->text(), &ok, this );
  609. eventLoopLeft();
  610. m_blockEmitDataChanged = false;
  611. if ( !ok || ( oldName == newName) ) // handle cancel
  612. return;
  613. setName( newName );
  614. }
  615. void KNote::slotUpdateReadOnly()
  616. {
  617. const bool readOnly = m_readOnly->isChecked();
  618. m_editor->setReadOnly( readOnly );
  619. m_config->setReadOnly( readOnly );
  620. // Enable/disable actions accordingly
  621. actionCollection()->action( "configure_note" )->setEnabled( !readOnly );
  622. actionCollection()->action( "insert_date" )->setEnabled( !readOnly );
  623. actionCollection()->action( "delete_note" )->setEnabled( !readOnly );
  624. actionCollection()->action( "edit_undo" )->setEnabled( !readOnly && m_editor->isUndoAvailable() );
  625. actionCollection()->action( "edit_redo" )->setEnabled( !readOnly && m_editor->isRedoAvailable() );
  626. actionCollection()->action( "edit_cut" )->setEnabled( !readOnly && m_editor->hasSelectedText() );
  627. actionCollection()->action( "edit_paste" )->setEnabled( !readOnly );
  628. actionCollection()->action( "edit_clear" )->setEnabled( !readOnly );
  629. actionCollection()->action( "rename_note" )->setEnabled( !readOnly );
  630. actionCollection()->action( "format_bold" )->setEnabled( !readOnly );
  631. actionCollection()->action( "format_italic" )->setEnabled( !readOnly );
  632. actionCollection()->action( "format_underline" )->setEnabled( !readOnly );
  633. actionCollection()->action( "format_strikeout" )->setEnabled( !readOnly );
  634. actionCollection()->action( "format_alignleft" )->setEnabled( !readOnly );
  635. actionCollection()->action( "format_aligncenter" )->setEnabled( !readOnly );
  636. actionCollection()->action( "format_alignright" )->setEnabled( !readOnly );
  637. actionCollection()->action( "format_alignblock" )->setEnabled( !readOnly );
  638. actionCollection()->action( "format_list" )->setEnabled( !readOnly );
  639. actionCollection()->action( "format_super" )->setEnabled( !readOnly );
  640. actionCollection()->action( "format_sub" )->setEnabled( !readOnly );
  641. actionCollection()->action( "format_size" )->setEnabled( !readOnly );
  642. actionCollection()->action( "format_color" )->setEnabled( !readOnly );
  643. updateFocus();
  644. }
  645. void KNote::slotClose()
  646. {
  647. NETWinInfo wm_client( tqt_xdisplay(), winId(), tqt_xrootwin(), NET::WMDesktop );
  648. if ( wm_client.desktop() == NETWinInfo::OnAllDesktops || wm_client.desktop() > 0 )
  649. m_config->setDesktop( wm_client.desktop() );
  650. m_editor->clearFocus();
  651. m_config->setHideNote( true );
  652. m_config->setPosition( pos() );
  653. // just hide the note so it's still available from the dock window
  654. hide();
  655. }
  656. void KNote::slotInsDate()
  657. {
  658. m_editor->insert( TDEGlobal::locale()->formatDateTime(TQDateTime::currentDateTime()) );
  659. }
  660. void KNote::slotSetAlarm()
  661. {
  662. m_blockEmitDataChanged = true;
  663. KNoteAlarmDlg dlg( name(), this );
  664. dlg.setIncidence( m_journal );
  665. aboutToEnterEventLoop();
  666. if ( dlg.exec() == TQDialog::Accepted )
  667. emit sigDataChanged(noteId());
  668. eventLoopLeft();
  669. m_blockEmitDataChanged = false;
  670. }
  671. void KNote::slotPreferences()
  672. {
  673. // reuse if possible
  674. if ( KNoteConfigDlg::showDialog( noteId().utf8() ) )
  675. return;
  676. // create a new preferences dialog...
  677. KNoteConfigDlg *dialog = new KNoteConfigDlg( m_config, name(), this, noteId().utf8() );
  678. connect( dialog, TQT_SIGNAL(settingsChanged()), TQT_TQOBJECT(this), TQT_SLOT(slotApplyConfig()) );
  679. connect( this, TQT_SIGNAL(sigNameChanged()), dialog, TQT_SLOT(slotUpdateCaption()) );
  680. dialog->show();
  681. }
  682. void KNote::slotSend()
  683. {
  684. // pop up dialog to get the IP
  685. KNoteHostDlg hostDlg( i18n("Send \"%1\"").arg( name() ), this );
  686. aboutToEnterEventLoop();
  687. bool ok = (hostDlg.exec() == TQDialog::Accepted);
  688. eventLoopLeft();
  689. if ( !ok ) // handle cancel
  690. return;
  691. TQString host = hostDlg.host();
  692. if ( host.isEmpty() )
  693. {
  694. KMessageBox::sorry( this, i18n("The host cannot be empty.") );
  695. return;
  696. }
  697. // Send the note
  698. KNotesNetworkSender *sender = new KNotesNetworkSender( host, KNotesGlobalConfig::port() );
  699. sender->setSenderId( KNotesGlobalConfig::senderID() );
  700. sender->setNote( name(), text() );
  701. sender->connect();
  702. }
  703. void KNote::slotMail()
  704. {
  705. // get the mail action command
  706. const TQStringList cmd_list = TQStringList::split( TQChar(' '), KNotesGlobalConfig::mailAction() );
  707. TDEProcess mail;
  708. for ( TQStringList::ConstIterator it = cmd_list.constBegin();
  709. it != cmd_list.constEnd(); ++it )
  710. {
  711. if ( *it == "%f" )
  712. mail << plainText().local8Bit(); // convert rich text to plain text
  713. else if ( *it == "%t" )
  714. mail << m_label->text().local8Bit();
  715. else
  716. mail << (*it).local8Bit();
  717. }
  718. if ( !mail.start( TDEProcess::DontCare ) )
  719. KMessageBox::sorry( this, i18n("Unable to start the mail process.") );
  720. }
  721. void KNote::slotPrint()
  722. {
  723. TQString content;
  724. if ( m_editor->textFormat() == PlainText )
  725. content = TQStyleSheet::convertFromPlainText( m_editor->text() );
  726. else
  727. content = m_editor->text();
  728. KNotePrinter printer;
  729. printer.setMimeSourceFactory( m_editor->mimeSourceFactory() );
  730. printer.setFont( m_config->font() );
  731. printer.setContext( m_editor->context() );
  732. printer.setStyleSheet( m_editor->styleSheet() );
  733. printer.setColorGroup( colorGroup() );
  734. printer.printNote( TQString(), content );
  735. }
  736. void KNote::slotSaveAs()
  737. {
  738. m_blockEmitDataChanged = true;
  739. TQCheckBox *convert = 0;
  740. if ( m_editor->textFormat() == RichText )
  741. {
  742. convert = new TQCheckBox( 0 );
  743. convert->setText( i18n("Save note as plain text") );
  744. }
  745. KFileDialog dlg( TQString(), TQString(), this, "filedialog", true, convert );
  746. dlg.setOperationMode( KFileDialog::Saving );
  747. dlg.setCaption( i18n("Save As") );
  748. aboutToEnterEventLoop();
  749. dlg.exec();
  750. eventLoopLeft();
  751. TQString fileName = dlg.selectedFile();
  752. if ( fileName.isEmpty() )
  753. {
  754. m_blockEmitDataChanged = false;
  755. return;
  756. }
  757. TQFile file( fileName );
  758. if ( file.exists() &&
  759. KMessageBox::warningContinueCancel( this, i18n("<qt>A file named <b>%1</b> already exists.<br>"
  760. "Are you sure you want to overwrite it?</qt>").arg( TQFileInfo(file).fileName() ) )
  761. != KMessageBox::Continue )
  762. {
  763. m_blockEmitDataChanged = false;
  764. return;
  765. }
  766. if ( file.open( IO_WriteOnly ) )
  767. {
  768. TQTextStream stream( &file );
  769. // convert rich text to plain text first
  770. if ( convert && convert->isChecked() )
  771. stream << plainText();
  772. else
  773. stream << text();
  774. }
  775. m_blockEmitDataChanged = false;
  776. }
  777. void KNote::slotPopupActionToDesktop( int id )
  778. {
  779. toDesktop( id - 1 ); // compensate for the menu separator, -1 == all desktops
  780. }
  781. // ------------------ private slots (configuration) ------------------ //
  782. void KNote::slotApplyConfig()
  783. {
  784. if ( m_config->richText() )
  785. m_editor->setTextFormat( RichText );
  786. else
  787. m_editor->setTextFormat( PlainText );
  788. m_label->setFont( m_config->titleFont() );
  789. m_editor->setTextFont( m_config->font() );
  790. m_editor->setTabStop( m_config->tabSize() );
  791. m_editor->setAutoIndentMode( m_config->autoIndent() );
  792. // if called as a slot, save the text, we might have changed the
  793. // text format - otherwise the journal will not be updated
  794. if ( sender() )
  795. saveData();
  796. setColor( m_config->fgColor(), m_config->bgColor() );
  797. updateLabelAlignment();
  798. slotUpdateShowInTaskbar();
  799. }
  800. void KNote::slotUpdateKeepAboveBelow()
  801. {
  802. KWin::WindowInfo info( KWin::windowInfo( winId() ) );
  803. if ( m_keepAbove->isChecked() )
  804. {
  805. m_config->setKeepAbove( true );
  806. m_config->setKeepBelow( false );
  807. KWin::setState( winId(), info.state() | NET::KeepAbove );
  808. }
  809. else if ( m_keepBelow->isChecked() )
  810. {
  811. m_config->setKeepAbove( false );
  812. m_config->setKeepBelow( true );
  813. KWin::setState( winId(), info.state() | NET::KeepBelow );
  814. }
  815. else
  816. {
  817. m_config->setKeepAbove( false );
  818. KWin::clearState( winId(), NET::KeepAbove );
  819. m_config->setKeepBelow( false );
  820. KWin::clearState( winId(), NET::KeepBelow );
  821. }
  822. }
  823. void KNote::slotUpdateShowInTaskbar()
  824. {
  825. if ( !m_config->showInTaskbar() )
  826. KWin::setState( winId(), KWin::windowInfo(winId()).state() | NET::SkipTaskbar );
  827. else
  828. KWin::clearState( winId(), NET::SkipTaskbar );
  829. }
  830. void KNote::slotUpdateDesktopActions()
  831. {
  832. NETRootInfo wm_root( tqt_xdisplay(), NET::NumberOfDesktops | NET::DesktopNames );
  833. NETWinInfo wm_client( tqt_xdisplay(), winId(), tqt_xrootwin(), NET::WMDesktop );
  834. TQStringList desktops;
  835. desktops.append( i18n("&All Desktops") );
  836. desktops.append( TQString() ); // Separator
  837. int count = wm_root.numberOfDesktops();
  838. for ( int n = 1; n <= count; n++ )
  839. desktops.append( TQString("&%1 %2").arg( n ).arg( TQString::fromUtf8(wm_root.desktopName( n )) ) );
  840. m_toDesktop->setItems( desktops );
  841. if ( wm_client.desktop() == NETWinInfo::OnAllDesktops )
  842. m_toDesktop->setCurrentItem( 0 );
  843. else
  844. m_toDesktop->setCurrentItem( wm_client.desktop() + 1 ); // compensate for separator (+1)
  845. }
  846. void KNote::slotUpdateViewport( int /*x*/, int y )
  847. {
  848. if ( s_ppOffset )
  849. updateBackground( y );
  850. }
  851. // -------------------- private methods -------------------- //
  852. void KNote::toDesktop( int desktop )
  853. {
  854. if ( desktop == 0 )
  855. return;
  856. if ( desktop == NETWinInfo::OnAllDesktops )
  857. KWin::setOnAllDesktops( winId(), true );
  858. else
  859. KWin::setOnDesktop( winId(), desktop );
  860. }
  861. void KNote::createFold()
  862. {
  863. TQPixmap fold( 15, 15 );
  864. TQPainter foldp( &fold );
  865. foldp.setPen( TQt::NoPen );
  866. foldp.setBrush( palette().active().dark() );
  867. TQPointArray foldpoints( 3 );
  868. foldpoints.putPoints( 0, 3, 0, 0, 14, 0, 0, 14 );
  869. foldp.drawPolygon( foldpoints );
  870. foldp.end();
  871. m_fold->setPixmap( fold );
  872. }
  873. void KNote::updateLabelAlignment()
  874. {
  875. // if the name is too long to fit, left-align it, otherwise center it (#59028)
  876. TQString labelText = m_label->text();
  877. if ( m_label->fontMetrics().boundingRect( labelText ).width() > m_label->width() )
  878. m_label->setAlignment( AlignLeft );
  879. else
  880. m_label->setAlignment( AlignHCenter );
  881. }
  882. void KNote::updateFocus()
  883. {
  884. if ( hasFocus() )
  885. {
  886. m_label->setBackgroundColor( palette().active().shadow() );
  887. m_button->show();
  888. if ( !m_editor->isReadOnly() )
  889. {
  890. if ( m_tool && m_tool->isHidden() && m_editor->textFormat() == TQTextEdit::RichText )
  891. {
  892. m_tool->show();
  893. updateLayout(); // to update the editor height
  894. }
  895. m_editor->cornerWidget()->show();
  896. }
  897. else
  898. {
  899. if ( m_tool && !m_tool->isHidden() )
  900. {
  901. m_tool->hide();
  902. updateLayout(); // to update the minimum height
  903. }
  904. m_editor->cornerWidget()->hide();
  905. }
  906. m_fold->hide();
  907. }
  908. else
  909. {
  910. m_button->hide();
  911. m_editor->cornerWidget()->hide();
  912. if ( m_tool && !m_tool->isHidden() )
  913. {
  914. m_tool->hide();
  915. updateLayout(); // to update the minimum height
  916. }
  917. if ( s_ppOffset )
  918. {
  919. m_label->setBackgroundColor( palette().active().midlight() );
  920. m_fold->show();
  921. }
  922. else
  923. m_label->setBackgroundColor( palette().active().background() );
  924. }
  925. }
  926. void KNote::updateMask()
  927. {
  928. if ( !s_ppOffset )
  929. {
  930. clearMask();
  931. return;
  932. }
  933. int w = width();
  934. int h = height();
  935. TQRegion reg( 0, s_ppOffset, w, h - s_ppOffset );
  936. const TQBitmap *pushpin_bitmap = m_pushpin->pixmap()->mask();
  937. TQRegion pushpin_reg( *pushpin_bitmap );
  938. m_pushpin->setMask( pushpin_reg );
  939. pushpin_reg.translate( m_pushpin->x(), m_pushpin->y() );
  940. if ( !hasFocus() )
  941. {
  942. TQPointArray foldpoints( 3 );
  943. foldpoints.putPoints( 0, 3, w-15, h, w, h-15, w, h );
  944. TQRegion fold( foldpoints, false );
  945. setMask( reg.unite( pushpin_reg ).subtract( fold ) );
  946. }
  947. else
  948. setMask( reg.unite( pushpin_reg ) );
  949. }
  950. void KNote::updateBackground( int y_offset )
  951. {
  952. if ( !s_ppOffset )
  953. {
  954. m_editor->setPaper( TQBrush( colorGroup().background() ) );
  955. return;
  956. }
  957. int w = m_editor->visibleWidth();
  958. int h = m_editor->visibleHeight();
  959. // in case y_offset is not set, calculate y_offset as the content
  960. // y-coordinate of the top-left point of the viewport - which is essentially
  961. // the vertical scroll amount
  962. if ( y_offset == -1 )
  963. y_offset = m_editor->contentsY();
  964. y_offset = y_offset % h;
  965. TQImage grad_img( w, h, 32 );
  966. TQRgb rgbcol;
  967. TQColor bg = palette().active().background();
  968. for ( int i = 0; i < h; ++i )
  969. {
  970. // if the scrollbar has moved, then adjust the gradient by the amount the
  971. // scrollbar moved -- so that the background gradient looks ok when tiled
  972. // the lightness is calculated as follows:
  973. // if i >= y, then lightness = 150 - (i-y)*75/h;
  974. // if i < y, then lightness = 150 - (i+h-y)*75/h
  975. int i_1 = 150 - 75 * ((i - y_offset + h) % h) / h;
  976. rgbcol = bg.light( i_1 ).rgb();
  977. for ( int j = 0; j < w; ++j )
  978. grad_img.setPixel( j, i, rgbcol );
  979. }
  980. // setPaletteBackgroundPixmap makes TQTextEdit::color() stop working!!
  981. m_editor->setPaper( TQBrush( TQt::black, TQPixmap( grad_img ) ) );
  982. }
  983. void KNote::updateLayout()
  984. {
  985. const int headerHeight = m_label->sizeHint().height();
  986. const int margin = m_editor->margin();
  987. bool closeLeft = false;
  988. m_twinConf->setGroup( "Style" );
  989. if ( m_twinConf->readBoolEntry( "CustomButtonPositions" ) )
  990. closeLeft = m_twinConf->readEntry( "ButtonsOnLeft" ).find( 'X' ) > -1;
  991. if ( s_ppOffset )
  992. {
  993. if ( !m_editor->paper().pixmap() ) // just changed the style
  994. setColor( palette().active().foreground(), palette().active().background() );
  995. m_pushpin->show();
  996. setFrameStyle( Panel | Raised );
  997. if ( closeLeft )
  998. m_pushpin->move( width() - m_pushpin->width(), 0 );
  999. else
  1000. m_pushpin->move( 0, 0 );
  1001. }
  1002. else
  1003. {
  1004. if ( m_editor->paper().pixmap() ) // just changed the style
  1005. setColor( palette().active().foreground(), palette().active().background() );
  1006. setFrameStyle( WinPanel | Raised );
  1007. m_pushpin->hide();
  1008. m_fold->hide();
  1009. }
  1010. m_button->setGeometry(
  1011. closeLeft ? contentsRect().x() : contentsRect().width() - headerHeight,
  1012. contentsRect().y() + s_ppOffset,
  1013. headerHeight,
  1014. headerHeight
  1015. );
  1016. m_label->setGeometry(
  1017. contentsRect().x(), contentsRect().y() + s_ppOffset,
  1018. contentsRect().width(), headerHeight
  1019. );
  1020. m_editor->setGeometry( TQRect(
  1021. TQPoint( contentsRect().x(),
  1022. contentsRect().y() + headerHeight + s_ppOffset ),
  1023. TQPoint( contentsRect().right(),
  1024. contentsRect().bottom() - ( m_tool ? (m_tool->isHidden() ? 0 : m_tool->height()) : 0 ) )
  1025. ) );
  1026. if( m_tool ) {
  1027. m_tool->setGeometry(
  1028. contentsRect().x(),
  1029. contentsRect().bottom() - m_tool->height() + 1,
  1030. contentsRect().width(),
  1031. m_tool->height()
  1032. );
  1033. }
  1034. if ( s_ppOffset )
  1035. m_fold->move( width() - 15, height() - 15 );
  1036. setMinimumSize(
  1037. m_editor->cornerWidget()->width() + margin*2,
  1038. headerHeight + s_ppOffset + ( m_tool ? m_tool->height() : 0 ) +
  1039. m_editor->cornerWidget()->height() + margin*2
  1040. );
  1041. updateLabelAlignment();
  1042. updateMask();
  1043. updateBackground();
  1044. }
  1045. // -------------------- protected methods -------------------- //
  1046. void KNote::drawFrame( TQPainter *p )
  1047. {
  1048. TQRect r = frameRect();
  1049. r.setTop( s_ppOffset );
  1050. if ( s_ppOffset )
  1051. qDrawShadePanel( p, r, colorGroup(), false, lineWidth() );
  1052. else
  1053. qDrawWinPanel( p, r, colorGroup(), false );
  1054. }
  1055. void KNote::showEvent( TQShowEvent * )
  1056. {
  1057. if ( m_config->hideNote() )
  1058. {
  1059. // KWin does not preserve these properties for hidden windows
  1060. slotUpdateKeepAboveBelow();
  1061. slotUpdateShowInTaskbar();
  1062. toDesktop( m_config->desktop() );
  1063. move( m_config->position() );
  1064. m_config->setHideNote( false );
  1065. }
  1066. }
  1067. void KNote::resizeEvent( TQResizeEvent *qre )
  1068. {
  1069. TQFrame::resizeEvent( qre );
  1070. updateLayout();
  1071. }
  1072. void KNote::closeEvent( TQCloseEvent *event )
  1073. {
  1074. if(kapp->sessionSaving())
  1075. return;
  1076. event->ignore(); //We don't want to close (and delete the widget). Just hide it
  1077. slotClose();
  1078. }
  1079. void KNote::dragEnterEvent( TQDragEnterEvent *e )
  1080. {
  1081. if ( !m_config->readOnly() )
  1082. e->accept( KColorDrag::canDecode( e ) );
  1083. }
  1084. void KNote::dropEvent( TQDropEvent *e )
  1085. {
  1086. if ( m_config->readOnly() )
  1087. return;
  1088. TQColor bg;
  1089. if ( KColorDrag::decode( e, bg ) )
  1090. setColor( paletteForegroundColor(), bg );
  1091. }
  1092. bool KNote::focusNextPrevChild( bool )
  1093. {
  1094. return true;
  1095. }
  1096. bool KNote::event( TQEvent *ev )
  1097. {
  1098. if ( ev->type() == TQEvent::LayoutHint )
  1099. {
  1100. updateLayout();
  1101. return true;
  1102. }
  1103. else
  1104. return TQFrame::event( ev );
  1105. }
  1106. bool KNote::eventFilter( TQObject *o, TQEvent *ev )
  1107. {
  1108. if ( ev->type() == TQEvent::DragEnter &&
  1109. KColorDrag::canDecode( static_cast<TQDragEnterEvent *>(ev) ) )
  1110. {
  1111. dragEnterEvent( static_cast<TQDragEnterEvent *>(ev) );
  1112. return true;
  1113. }
  1114. if ( ev->type() == TQEvent::Drop &&
  1115. KColorDrag::canDecode( static_cast<TQDropEvent *>(ev) ) )
  1116. {
  1117. dropEvent( static_cast<TQDropEvent *>(ev) );
  1118. return true;
  1119. }
  1120. if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_label) )
  1121. {
  1122. TQMouseEvent *e = (TQMouseEvent *)ev;
  1123. if ( ev->type() == TQEvent::MouseButtonDblClick )
  1124. {
  1125. if( !m_editor->isReadOnly())
  1126. slotRename();
  1127. }
  1128. if ( ev->type() == TQEvent::MouseButtonPress &&
  1129. (e->button() == Qt::LeftButton || e->button() == Qt::MidButton))
  1130. {
  1131. e->button() == Qt::LeftButton ? KWin::raiseWindow( winId() )
  1132. : KWin::lowerWindow( winId() );
  1133. XUngrabPointer( tqt_xdisplay(), GET_QT_X_TIME() );
  1134. NETRootInfo wm_root( tqt_xdisplay(), NET::WMMoveResize );
  1135. wm_root.moveResizeRequest( winId(), e->globalX(), e->globalY(), NET::Move );
  1136. return true;
  1137. }
  1138. #if KDE_IS_VERSION( 3, 5, 1 )
  1139. if ( ev->type() == TQEvent::MouseButtonRelease )
  1140. {
  1141. NETRootInfo wm_root( tqt_xdisplay(), NET::WMMoveResize );
  1142. wm_root.moveResizeRequest( winId(), e->globalX(), e->globalY(), NET::MoveResizeCancel );
  1143. return false;
  1144. }
  1145. #endif
  1146. if ( m_menu && ( ev->type() == TQEvent::MouseButtonPress )
  1147. && ( e->button() == Qt::RightButton ) )
  1148. {
  1149. m_menu->popup( TQCursor::pos() );
  1150. return true;
  1151. }
  1152. return false;
  1153. }
  1154. if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_editor) ) {
  1155. if ( ev->type() == TQEvent::FocusOut ) {
  1156. TQFocusEvent *fe = TQT_TQFOCUSEVENT(ev);
  1157. if ( fe->reason() != TQFocusEvent::Popup &&
  1158. fe->reason() != TQFocusEvent::Mouse ) {
  1159. updateFocus();
  1160. if ( isModified() ) {
  1161. saveConfig();
  1162. if ( !m_blockEmitDataChanged )
  1163. saveData();
  1164. }
  1165. }
  1166. } else if ( ev->type() == TQEvent::FocusIn ) {
  1167. updateFocus();
  1168. }
  1169. return false;
  1170. }
  1171. if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_editor->viewport()) )
  1172. {
  1173. if ( m_edit_menu &&
  1174. ev->type() == TQEvent::MouseButtonPress &&
  1175. ((TQMouseEvent *)ev)->button() == Qt::RightButton )
  1176. {
  1177. m_edit_menu->popup( TQCursor::pos() );
  1178. return true;
  1179. }
  1180. }
  1181. return false;
  1182. }
  1183. void KNote::slotSaveData()
  1184. {
  1185. saveData();
  1186. }
  1187. void KNote::deleteWhenIdle()
  1188. {
  1189. if ( m_busy <= 0 )
  1190. deleteLater();
  1191. else
  1192. m_deleteWhenIdle = true;
  1193. }
  1194. void KNote::aboutToEnterEventLoop()
  1195. {
  1196. ++m_busy;
  1197. }
  1198. void KNote::eventLoopLeft()
  1199. {
  1200. --m_busy;
  1201. if ( m_busy <= 0 && m_deleteWhenIdle )
  1202. deleteLater();
  1203. }
  1204. #include "knote.moc"
  1205. #include "knotebutton.moc"