00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <QBoxLayout>
00022 #include <QCheckBox>
00023 #include <QFile>
00024 #include <QHBoxLayout>
00025 #include <QLabel>
00026 #include <QObject>
00027 #include <QPixmap>
00028 #include <QSize>
00029 #include <QSizeGrip>
00030 #include <QTextStream>
00031 #include <QVBoxLayout>
00032 #include <QDesktopWidget>
00033
00034 #include <k3colordrag.h>
00035 #include <kaction.h>
00036 #include <kactioncollection.h>
00037 #include <kapplication.h>
00038 #include <kcal/journal.h>
00039 #include <kcodecs.h>
00040 #include <kcombobox.h>
00041 #include <kdebug.h>
00042 #include <kfiledialog.h>
00043 #include <kfind.h>
00044 #include <kglobalsettings.h>
00045 #include <kicon.h>
00046 #include <kiconeffect.h>
00047 #include <kiconloader.h>
00048 #include <kinputdialog.h>
00049 #include <kio/netaccess.h>
00050 #include <klocale.h>
00051 #include <kmenu.h>
00052 #include <kmessagebox.h>
00053 #include <kprocess.h>
00054 #include <kselectaction.h>
00055 #include <ksocketfactory.h>
00056 #include <kstandardaction.h>
00057 #include <kstandarddirs.h>
00058 #include <ktoggleaction.h>
00059 #include <ktoolbar.h>
00060 #include <kwindowsystem.h>
00061 #include <kxmlguibuilder.h>
00062 #include <kxmlguifactory.h>
00063 #include <netwm.h>
00064 #include <kdeversion.h>
00065
00066 #ifdef Q_WS_X11
00067 #include <fixx11h.h>
00068 #include <QX11Info>
00069 #endif
00070
00071 #include "knote.h"
00072 #include "knotealarmdlg.h"
00073 #include "knotebutton.h"
00074 #include "knoteconfig.h"
00075 #include "knoteconfigdlg.h"
00076 #include "knoteedit.h"
00077 #include "knotehostdlg.h"
00078 #include "knoteprinter.h"
00079 #include "knotesglobalconfig.h"
00080 #include "knotesnetsend.h"
00081 #include "version.h"
00082
00083 using namespace KCal;
00084
00085
00086 KNote::KNote( QDomDocument buildDoc, Journal *j, QWidget *parent )
00087 : QFrame( parent, Qt::FramelessWindowHint ), m_label( 0 ), m_grip( 0 ),
00088 m_button( 0 ), m_tool( 0 ), m_editor( 0 ), m_config( 0 ), m_journal( j ),
00089 m_find( 0 ), m_kwinConf( KSharedConfig::openConfig( "kwinrc" ) )
00090 {
00091 setAcceptDrops( true );
00092 setAttribute( Qt::WA_DeleteOnClose );
00093 setDOMDocument( buildDoc );
00094 setObjectName( m_journal->uid() );
00095 setXMLFile( componentData().componentName() + "ui.rc", false, false );
00096
00097
00098 m_noteLayout = new QVBoxLayout( this );
00099 setLayout( m_noteLayout );
00100 m_noteLayout->setMargin( 0 );
00101
00102
00103
00104 if ( m_journal->summary().isNull() && m_journal->dtStart().isValid() ) {
00105 QString s = KGlobal::locale()->formatDateTime( m_journal->dtStart() );
00106 m_journal->setSummary( s );
00107 }
00108
00109 createActions();
00110
00111 buildGui();
00112
00113 prepare();
00114 }
00115
00116 KNote::~KNote()
00117 {
00118 delete m_config;
00119 }
00120
00121
00122
00123
00124 void KNote::slotKill( bool force )
00125 {
00126 if ( !force &&
00127 ( KMessageBox::warningContinueCancel( this,
00128 i18n( "<qt>Do you really want to delete note <b>%1</b>?</qt>",
00129 m_label->text() ),
00130 i18n( "Confirm Delete" ),
00131 KGuiItem( i18n( "&Delete" ), "edit-delete" ),
00132 KStandardGuiItem::cancel(),
00133 "ConfirmDeleteNote" ) != KMessageBox::Continue ) ) {
00134 return;
00135 }
00136
00137
00138 delete m_config;
00139 m_config = 0;
00140
00141 QString configFile = KGlobal::dirs()->saveLocation( "appdata", "notes/" );
00142 configFile += m_journal->uid();
00143
00144 if ( !KIO::NetAccess::del( KUrl( configFile ), this ) ) {
00145 kError( 5500 ) <<"Can't remove the note config:" << configFile;
00146 }
00147
00148 emit sigKillNote( m_journal );
00149 }
00150
00151
00152
00153
00154 void KNote::saveData()
00155 {
00156 m_journal->setSummary( m_label->text() );
00157 m_journal->setDescription( m_editor->text() );
00158 m_journal->setCustomProperty( "KNotes", "FgColor",
00159 m_config->fgColor().name() );
00160 m_journal->setCustomProperty( "KNotes", "BgColor",
00161 m_config->bgColor().name() );
00162 m_journal->setCustomProperty( "KNotes", "RichText",
00163 m_config->richText() ? "true" : "false" );
00164
00165 emit sigDataChanged();
00166 m_editor->document()->setModified( false );
00167 }
00168
00169 void KNote::saveConfig() const
00170 {
00171 m_config->setWidth( width() );
00172 if ( m_tool ) {
00173 m_config->setHeight(
00174 height() - ( m_tool->isHidden() ? 0 : m_tool->height() ) );
00175 } else {
00176 m_config->setHeight( 0 );
00177 }
00178 m_config->setPosition( pos() );
00179
00180 #ifdef Q_WS_X11
00181 NETWinInfo wm_client( QX11Info::display(), winId(),
00182 QX11Info::appRootWindow(), NET::WMDesktop );
00183 if ( ( wm_client.desktop() == NETWinInfo::OnAllDesktops ) ||
00184 ( wm_client.desktop() > 0 ) ) {
00185 m_config->setDesktop( wm_client.desktop() );
00186 }
00187 #endif
00188
00189
00190 m_config->writeConfig();
00191 }
00192
00193 QString KNote::noteId() const
00194 {
00195 return m_journal->uid();
00196 }
00197
00198 QString KNote::name() const
00199 {
00200 return m_label->text();
00201 }
00202
00203 QString KNote::text() const
00204 {
00205 return m_editor->text();
00206 }
00207
00208 void KNote::setName( const QString& name )
00209 {
00210 m_label->setText( name );
00211 updateLabelAlignment();
00212
00213 if ( m_editor ) {
00214 saveData();
00215 }
00216 #ifdef Q_WS_X11
00217
00218 NETWinInfo note_win( QX11Info::display(), winId(), QX11Info::appRootWindow(),
00219 NET::WMDesktop );
00220 note_win.setName( name.toUtf8() );
00221 #endif
00222
00223 emit sigNameChanged();
00224 }
00225
00226 void KNote::setText( const QString& text )
00227 {
00228 m_editor->setText( text );
00229
00230 saveData();
00231 }
00232
00233 void KNote::find( const QString& pattern, long options )
00234 {
00235 delete m_find;
00236 m_find = new KFind( pattern, options, this );
00237
00238 connect( m_find, SIGNAL( highlight( const QString &, int, int ) ),
00239 this, SLOT( slotHighlight( const QString &, int, int ) ) );
00240 connect( m_find, SIGNAL( findNext() ), this, SLOT( slotFindNext() ) );
00241
00242 m_find->setData( m_editor->toPlainText() );
00243 slotFindNext();
00244 }
00245
00246 void KNote::slotFindNext()
00247 {
00248
00249
00250
00251
00252
00253 KFind::Result res = m_find->find();
00254
00255 if ( res == KFind::NoMatch ) {
00256
00257 m_editor->textCursor().clearSelection();
00258 emit sigFindFinished();
00259 delete m_find;
00260 m_find = 0;
00261 } else {
00262 show();
00263 #ifdef Q_WS_X11
00264 KWindowSystem::setCurrentDesktop( KWindowSystem::windowInfo( winId(),
00265 NET::WMDesktop ).desktop() );
00266 #endif
00267 }
00268 }
00269
00270 void KNote::slotHighlight( const QString& , int idx, int len )
00271 {
00272 QTextCursor c = m_editor->textCursor();
00273 c.setPosition( idx );
00274 c.setPosition( idx + len, QTextCursor::KeepAnchor );
00275
00276 }
00277
00278 bool KNote::isModified() const
00279 {
00280 return m_editor->document()->isModified();
00281 }
00282
00283
00284
00285 void KNote::slotRename()
00286 {
00287
00288 bool ok;
00289 QString newName = KInputDialog::getText( QString::null,
00290
00291 i18n( "Please enter the new name:" ), m_label->text(), &ok, this );
00292
00293 if ( !ok ) {
00294 return;
00295 }
00296
00297 setName( newName );
00298 }
00299
00300 void KNote::slotUpdateReadOnly()
00301 {
00302 const bool readOnly = m_readOnly->isChecked();
00303
00304 m_editor->setReadOnly( readOnly );
00305 m_config->setReadOnly( readOnly );
00306
00307
00308 actionCollection()->action( "configure_note" )->setEnabled( !readOnly );
00309 actionCollection()->action( "insert_date" )->setEnabled( !readOnly );
00310 actionCollection()->action( "delete_note" )->setEnabled( !readOnly );
00311
00312 actionCollection()->action( "edit_undo" )->setEnabled( !readOnly &&
00313 m_editor->document()->isUndoAvailable() );
00314 actionCollection()->action( "edit_redo" )->setEnabled( !readOnly &&
00315 m_editor->document()->isRedoAvailable() );
00316 actionCollection()->action( "edit_cut" )->setEnabled( !readOnly &&
00317 m_editor->textCursor().hasSelection() );
00318 actionCollection()->action( "edit_paste" )->setEnabled( !readOnly );
00319 actionCollection()->action( "edit_clear" )->setEnabled( !readOnly );
00320
00321 updateFocus();
00322 }
00323
00324 void KNote::slotClose()
00325 {
00326 #ifdef Q_WS_X11
00327 NETWinInfo wm_client( QX11Info::display(), winId(),
00328 QX11Info::appRootWindow(), NET::WMDesktop );
00329 if ( ( wm_client.desktop() == NETWinInfo::OnAllDesktops ) ||
00330 ( wm_client.desktop() > 0 ) ) {
00331 m_config->setDesktop( wm_client.desktop() );
00332 }
00333 #endif
00334
00335 m_editor->clearFocus();
00336 m_config->setHideNote( true );
00337 m_config->setPosition( pos() );
00338
00339
00340 hide();
00341 }
00342
00343 void KNote::slotInsDate()
00344 {
00345 m_editor->insertPlainText(
00346 KGlobal::locale()->formatDateTime( QDateTime::currentDateTime() ) );
00347 }
00348
00349 void KNote::slotSetAlarm()
00350 {
00351 KNoteAlarmDlg dlg( name(), this );
00352 dlg.setIncidence( m_journal );
00353
00354 if ( dlg.exec() == QDialog::Accepted ) {
00355 emit sigDataChanged();
00356 }
00357 }
00358
00359 void KNote::slotPreferences()
00360 {
00361
00362 if ( KNoteConfigDlg::showDialog( noteId() ) ) {
00363 return;
00364 }
00365
00366
00367 KNoteConfigDlg *dialog = new KNoteConfigDlg( m_config, name(), this, noteId() );
00368 connect( dialog, SIGNAL( settingsChanged( const QString & ) ) , this,
00369 SLOT( slotApplyConfig() ) );
00370 connect( this, SIGNAL( sigNameChanged() ), dialog,
00371 SLOT( slotUpdateCaption() ) );
00372 dialog->show();
00373 }
00374
00375 void KNote::slotSend()
00376 {
00377
00378 KNoteHostDlg hostDlg( i18n( "Send \"%1\"", name() ), this );
00379 bool ok = ( hostDlg.exec() == QDialog::Accepted );
00380 QString host = hostDlg.host();
00381
00382 if ( !ok ) {
00383 return;
00384 }
00385
00386 if ( host.isEmpty() ) {
00387 KMessageBox::sorry( this, i18n( "The host cannot be empty." ) );
00388 return;
00389 }
00390
00391
00392
00393 KNotesNetworkSender *sender = new KNotesNetworkSender(
00394 KSocketFactory::connectToHost( "knotes", host,
00395 KNotesGlobalConfig::port() ) );
00396 sender->setSenderId( KNotesGlobalConfig::senderID() );
00397 sender->setNote( name(), text() );
00398 }
00399
00400 void KNote::slotMail()
00401 {
00402
00403 QStringList cmd_list = KNotesGlobalConfig::mailAction().split( QChar(' '),
00404 QString::SkipEmptyParts );
00405
00406 KProcess mail;
00407 foreach ( const QString& cmd, cmd_list ) {
00408 if ( cmd == "%f" ) {
00409 mail << m_editor->toPlainText();
00410 } else if ( cmd == "%t" ) {
00411 mail << m_label->text();
00412 } else {
00413 mail << cmd;
00414 }
00415 }
00416
00417 if ( !mail.startDetached() ) {
00418 KMessageBox::sorry( this, i18n( "Unable to start the mail process." ) );
00419 }
00420 }
00421
00422 void KNote::slotPrint()
00423 {
00424 saveData();
00425 QString content;
00426 if ( !Qt::mightBeRichText( m_editor->text() ) ) {
00427 content = Qt::convertFromPlainText( m_editor->text() );
00428 } else {
00429 content = m_editor->text();
00430 }
00431 KNotePrinter printer;
00432 printer.setDefaultFont( m_config->font() );
00433 printer.printNote( name(), content );
00434 }
00435
00436 void KNote::slotSaveAs()
00437 {
00438
00439
00440 QCheckBox *convert = 0;
00441
00442 if ( m_editor->acceptRichText() ) {
00443 convert = new QCheckBox( 0 );
00444 convert->setText( i18n( "Save note as plain text" ) );
00445 }
00446
00447 KUrl url;
00448 KFileDialog dlg( url, QString(), this, convert );
00449 dlg.setOperationMode( KFileDialog::Saving );
00450 dlg.setCaption( i18n( "Save As" ) );
00451 dlg.exec();
00452
00453 QString fileName = dlg.selectedFile();
00454 if ( fileName.isEmpty() ) {
00455 return;
00456 }
00457
00458 QFile file( fileName );
00459
00460 if ( file.exists() &&
00461 KMessageBox::warningContinueCancel( this,
00462 i18n( "<qt>A file named <b>%1</b> already exists.<br />"
00463 "Are you sure you want to overwrite it?</qt>",
00464 QFileInfo( file ).fileName() ) ) != KMessageBox::Continue ) {
00465 return;
00466 }
00467
00468 if ( file.open( QIODevice::WriteOnly ) ) {
00469 QTextStream stream( &file );
00470 if ( convert && !convert->isChecked() ) {
00471 stream << m_editor->toHtml();
00472 } else {
00473 stream << m_editor->toPlainText();
00474 }
00475 }
00476 }
00477
00478 void KNote::slotPopupActionToDesktop( int id )
00479 {
00480 toDesktop( id - 1 );
00481 }
00482
00483
00484
00485
00486 void KNote::slotApplyConfig()
00487 {
00488 m_label->setFont( m_config->titleFont() );
00489 m_editor->setRichText( m_config->richText() );
00490 m_editor->setTextFont( m_config->font() );
00491 m_editor->setTabStop( m_config->tabSize() );
00492 m_editor->setAutoIndentMode( m_config->autoIndent() );
00493
00494
00495
00496 if ( sender() ) {
00497 saveData();
00498 }
00499
00500 setColor( m_config->fgColor(), m_config->bgColor() );
00501
00502 updateLayout();
00503 slotUpdateShowInTaskbar();
00504 }
00505
00506 void KNote::slotUpdateKeepAboveBelow()
00507 {
00508 #ifdef Q_WS_X11
00509 unsigned long state = KWindowInfo( KWindowSystem::windowInfo( winId(), NET::WMState ) ).state();
00510 #else
00511 unsigned long state = 0;
00512 #endif
00513 if ( m_keepAbove->isChecked() ) {
00514 m_config->setKeepAbove( true );
00515 m_config->setKeepBelow( false );
00516 KWindowSystem::setState( winId(), state | NET::KeepAbove );
00517 } else if ( m_keepBelow->isChecked() ) {
00518 m_config->setKeepAbove( false );
00519 m_config->setKeepBelow( true );
00520 KWindowSystem::setState( winId(), state | NET::KeepBelow );
00521 } else {
00522 m_config->setKeepAbove( false );
00523 KWindowSystem::clearState( winId(), NET::KeepAbove );
00524 m_config->setKeepBelow( false );
00525 KWindowSystem::clearState( winId(), NET::KeepBelow );
00526 }
00527 }
00528
00529 void KNote::slotUpdateShowInTaskbar()
00530 {
00531 #ifdef Q_WS_X11
00532 if ( !m_config->showInTaskbar() ) {
00533 KWindowSystem::setState( winId(), KWindowSystem::windowInfo( winId(),
00534 NET::WMState ).state() | NET::SkipTaskbar );
00535 } else {
00536 KWindowSystem::clearState( winId(), NET::SkipTaskbar );
00537 }
00538 #endif
00539 }
00540
00541 void KNote::slotUpdateDesktopActions()
00542 {
00543 #ifdef Q_WS_X11
00544 NETRootInfo wm_root( QX11Info::display(), NET::NumberOfDesktops |
00545 NET::DesktopNames );
00546 NETWinInfo wm_client( QX11Info::display(), winId(),
00547 QX11Info::appRootWindow(), NET::WMDesktop );
00548
00549 QStringList desktops;
00550 desktops.append( i18n( "&All Desktops" ) );
00551 desktops.append( QString::null );
00552
00553
00554
00555 int count = wm_root.numberOfDesktops();
00556 for ( int n = 1; n <= count; n++ ) {
00557 desktops.append( QString( "&%1 %2" ).arg( n ).arg(
00558 QString::fromUtf8( wm_root.desktopName( n ) ) ) );
00559 }
00560 m_toDesktop->setItems( desktops );
00561
00562 if ( wm_client.desktop() == NETWinInfo::OnAllDesktops ) {
00563 m_toDesktop->setCurrentItem( 0 );
00564 } else {
00565 m_toDesktop->setCurrentItem( wm_client.desktop() + 1 );
00566
00567 }
00568 #endif
00569 }
00570
00571
00572
00573
00574 void KNote::buildGui()
00575 {
00576 createNoteHeader();
00577 createNoteEditor();
00578
00579 KXMLGUIBuilder builder( this );
00580 KXMLGUIFactory factory( &builder, this );
00581 factory.addClient( this );
00582
00583 m_menu = dynamic_cast<KMenu*>( factory.container( "note_context", this ) );
00584 m_editor->setContextMenu( dynamic_cast<KMenu *>(
00585 factory.container( "note_edit", this ) ) );
00586 m_tool = dynamic_cast<KToolBar*>( factory.container( "note_tool", this ) );
00587
00588 createNoteFooter();
00589 }
00590
00591 void KNote::createActions()
00592 {
00593
00594
00595 KAction *action;
00596
00597 action = new KAction( KIcon( "document-new" ), i18n( "New" ), this );
00598 actionCollection()->addAction( "new_note", action );
00599 connect( action, SIGNAL( triggered( bool ) ), SIGNAL( sigRequestNewNote() ) );
00600
00601 action = new KAction( KIcon( "edit-rename" ), i18n( "Rename..." ), this );
00602 actionCollection()->addAction( "rename_note", action );
00603 connect( action, SIGNAL( triggered( bool ) ), SLOT( slotRename() ) );
00604
00605 m_readOnly = new KToggleAction( KIcon( "system-lock-screen" ),
00606 i18n( "Lock" ), this );
00607 actionCollection()->addAction( "lock_note", m_readOnly );
00608 connect( m_readOnly, SIGNAL( triggered( bool ) ),
00609 SLOT( slotUpdateReadOnly() ) );
00610 m_readOnly->setCheckedState( KGuiItem( i18n( "Unlock" ), "unlock" ) );
00611
00612 action = new KAction( KIcon( "window-close" ), i18n( "Hide" ), this );
00613 actionCollection()->addAction( "hide_note", action );
00614 connect( action, SIGNAL( triggered( bool ) ), SLOT( slotClose() ) );
00615 action->setShortcut( QKeySequence( Qt::Key_Escape ) );
00616
00617 action = new KAction( KIcon( "edit-delete" ), i18n( "Delete" ), this );
00618 actionCollection()->addAction( "delete_note", action );
00619 connect( action, SIGNAL( triggered( bool ) ), SLOT( slotKill() ) );
00620
00621 action = new KAction( KIcon( "knotes_date" ), i18n( "Insert Date" ), this );
00622 actionCollection()->addAction( "insert_date", action );
00623 connect( action, SIGNAL( triggered( bool ) ), SLOT( slotInsDate() ) );
00624
00625 action = new KAction( KIcon( "knotes_alarm" ), i18n( "Set Alarm..." ),
00626 this );
00627 actionCollection()->addAction( "set_alarm", action );
00628 connect( action, SIGNAL( triggered( bool ) ), SLOT( slotSetAlarm() ) );
00629
00630 action = new KAction( KIcon( "network-wired" ), i18n( "Send..." ), this );
00631 actionCollection()->addAction( "send_note", action );
00632 connect( action, SIGNAL( triggered( bool ) ), SLOT( slotSend() ) );
00633
00634 action = new KAction( KIcon( "mail-send" ), i18n( "Mail..." ), this );
00635 actionCollection()->addAction( "mail_note", action );
00636 connect( action, SIGNAL( triggered( bool ) ), SLOT( slotMail() ) );
00637
00638 action = new KAction( KIcon( "document-save-as" ), i18n( "Save As..." ),
00639 this );
00640 actionCollection()->addAction( "save_note", action );
00641 connect( action, SIGNAL( triggered( bool ) ), SLOT( slotSaveAs() ) );
00642 actionCollection()->addAction( KStandardAction::Print, "print_note", this,
00643 SLOT( slotPrint() ) );
00644
00645 action = new KAction( KIcon( "configure" ), i18n( "Preferences..." ), this );
00646 actionCollection()->addAction( "configure_note", action );
00647 connect( action, SIGNAL( triggered( bool ) ), SLOT( slotPreferences() ) );
00648
00649 QActionGroup *kab = new QActionGroup( this );
00650 kab->setExclusive( true );
00651
00652 m_keepAbove = new KToggleAction( KIcon( "go-up" ),
00653 i18n( "Keep Above Others" ), this );
00654 actionCollection()->addAction( "keep_above", m_keepAbove );
00655 connect( m_keepAbove, SIGNAL( triggered( bool ) ),
00656 SLOT( slotUpdateKeepAboveBelow() ) );
00657 kab->addAction( m_keepAbove );
00658
00659 m_keepBelow = new KToggleAction( KIcon( "go-down" ),
00660 i18n( "Keep Below Others" ), this );
00661 actionCollection()->addAction( "keep_below", m_keepBelow );
00662 connect( m_keepBelow, SIGNAL( triggered( bool ) ),
00663 SLOT( slotUpdateKeepAboveBelow() ) );
00664 kab->addAction( m_keepBelow );
00665
00666 #ifdef Q_WS_X11
00667 m_toDesktop = new KSelectAction( i18n( "To Desktop" ), this );
00668 actionCollection()->addAction( "to_desktop", m_toDesktop );
00669 connect( m_toDesktop, SIGNAL( triggered( int ) ),
00670 SLOT( slotPopupActionToDesktop( int ) ) );
00671 connect( m_toDesktop->menu(), SIGNAL( aboutToShow() ),
00672 SLOT( slotUpdateDesktopActions() ) );
00673 #endif
00674
00675
00676 action = new KAction( i18n( "Walk Through Notes" ), this );
00677 actionCollection()->addAction( "walk_notes", action );
00678 connect( action, SIGNAL( triggered( bool ) ), SIGNAL( sigShowNextNote() ) );
00679 action->setShortcut( QKeySequence( Qt::SHIFT + Qt::Key_Backtab ) );
00680
00681 actionCollection()->addAssociatedWidget( this );
00682 foreach (QAction* action, actionCollection()->actions())
00683 action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
00684 }
00685
00686 void KNote::createNoteHeader()
00687 {
00688
00689 KConfigGroup styleGroup( m_kwinConf, "Style" );
00690
00691 QBoxLayout::Direction headerLayoutDirection = QBoxLayout::LeftToRight;
00692
00693 if ( styleGroup.readEntry( "CustomButtonPositions", false ) ) {
00694 if ( styleGroup.readEntry( "ButtonsOnLeft" ).contains( 'X' ) ) {
00695 headerLayoutDirection = QBoxLayout::RightToLeft;
00696 }
00697 }
00698
00699 QBoxLayout *headerLayout = new QBoxLayout( headerLayoutDirection, this );
00700
00701
00702
00703 m_label = new QLabel( this );
00704 headerLayout->addWidget( m_label );
00705 m_label->setFrameStyle( NoFrame );
00706 m_label->setBackgroundRole( QPalette::Base );
00707 m_label->setLineWidth( 0 );
00708 m_label->setAutoFillBackground( true );
00709 m_label->installEventFilter( this );
00710
00711 setName( m_journal->summary() );
00712
00713 m_button = new KNoteButton( "knotes_close", this );
00714 headerLayout->addWidget( m_button );
00715
00716 connect( m_button, SIGNAL( clicked() ), this, SLOT( slotClose() ) );
00717
00718 m_noteLayout->addItem( headerLayout );
00719 }
00720
00721 void KNote::createNoteEditor()
00722 {
00723 m_editor = new KNoteEdit( actionCollection(), this );
00724 m_noteLayout->addWidget( m_editor );
00725 m_editor->installEventFilter( this );
00726 setFocusProxy( m_editor );
00727 }
00728
00729 void KNote::createNoteFooter()
00730 {
00731 if ( m_tool ) {
00732 m_tool->setIconSize( QSize( 10, 10 ) );
00733 m_tool->setFixedHeight( 24 );
00734 m_tool->setToolButtonStyle( Qt::ToolButtonIconOnly );
00735 }
00736
00737
00738 QHBoxLayout *gripLayout = new QHBoxLayout( this );
00739 m_grip = new QSizeGrip( this );
00740 m_grip->setFixedSize( m_grip->sizeHint() );
00741
00742 if ( m_tool ) {
00743 gripLayout->addWidget( m_tool );
00744 gripLayout->setAlignment( m_tool, Qt::AlignBottom | Qt::AlignLeft );
00745 m_tool->hide();
00746 }
00747
00748 gripLayout->addWidget( m_grip );
00749 gripLayout->setAlignment( m_grip, Qt::AlignBottom | Qt::AlignRight );
00750 m_noteLayout->addItem( gripLayout );
00751
00752
00753 foreach ( KComboBox *combo, m_tool->findChildren<KComboBox *>() ) {
00754 QFont font = combo->font();
00755 font.setPointSize( 7 );
00756 combo->setFont( font );
00757 combo->setFixedHeight( 14 );
00758 }
00759 }
00760
00761 void KNote::prepare()
00762 {
00763
00764 QString configFile = KGlobal::dirs()->saveLocation( "appdata", "notes/" );
00765 configFile += m_journal->uid();
00766
00767
00768
00769 bool newNote = !KIO::NetAccess::exists( KUrl( configFile ),
00770 KIO::NetAccess::DestinationSide, 0 );
00771
00772 m_config = new KNoteConfig( KSharedConfig::openConfig( configFile,
00773 KConfig::NoGlobals ) );
00774 m_config->readConfig();
00775 m_config->setVersion( KNOTES_VERSION );
00776
00777 if ( newNote ) {
00778
00779 KNotesGlobalConfig *globalConfig = KNotesGlobalConfig::self();
00780 m_config->setBgColor( globalConfig->bgColor() );
00781 m_config->setFgColor( globalConfig->fgColor() );
00782 m_config->setWidth( globalConfig->width() );
00783 m_config->setHeight( globalConfig->height() );
00784
00785 m_config->setFont( globalConfig->font() );
00786 m_config->setTitleFont( globalConfig->titleFont() );
00787 m_config->setAutoIndent( globalConfig->autoIndent() );
00788 m_config->setRichText( globalConfig->richText() );
00789 m_config->setTabSize( globalConfig->tabSize() );
00790 m_config->setReadOnly( globalConfig->readOnly() );
00791
00792 m_config->setDesktop( globalConfig->desktop() );
00793 m_config->setHideNote( globalConfig->hideNote() );
00794 m_config->setPosition( globalConfig->position() );
00795 m_config->setShowInTaskbar( globalConfig->showInTaskbar() );
00796 m_config->setRememberDesktop( globalConfig->rememberDesktop() );
00797 m_config->setKeepAbove( globalConfig->keepAbove() );
00798 m_config->setKeepBelow( globalConfig->keepBelow() );
00799
00800 m_config->writeConfig();
00801 }
00802
00803
00804 setFrameStyle( Panel | Raised );
00805 setMinimumSize( 20, 20 );
00806 setBackgroundRole( QPalette::Base );
00807
00808 m_editor->setContentsMargins( 0, 0, 0, 0 );
00809 m_editor->setBackgroundRole( QPalette::Base );
00810 m_editor->setFrameStyle( NoFrame );
00811 m_editor->setText( m_journal->description() );
00812 m_editor->document()->setModified( false );
00813
00814
00815 uint width = m_config->width();
00816 uint height = m_config->height();
00817 resize( width, height );
00818
00819
00820
00821 const QPoint& position = m_config->position();
00822 QRect desk = kapp->desktop()->rect();
00823 desk.adjust( 10, 10, -10, -10 );
00824 if ( desk.intersects( QRect( position, QSize( width, height ) ) ) ) {
00825 move( position );
00826 }
00827
00828
00829 QString property = m_journal->customProperty( "KNotes", "FgColor" );
00830 if ( !property.isNull() ) {
00831 m_config->setFgColor( QColor( property ) );
00832 } else {
00833 m_journal->setCustomProperty( "KNotes", "FgColor",
00834 m_config->fgColor().name() );
00835 }
00836
00837 property = m_journal->customProperty( "KNotes", "BgColor" );
00838 if ( !property.isNull() ) {
00839 m_config->setBgColor( QColor( property ) );
00840 } else {
00841 m_journal->setCustomProperty( "KNotes", "BgColor",
00842 m_config->bgColor().name() );
00843 }
00844 property = m_journal->customProperty( "KNotes", "RichText" );
00845 if ( !property.isNull() ) {
00846 m_config->setRichText( property == "true" ? true : false );
00847 } else {
00848 m_journal->setCustomProperty( "KNotes", "RichText",
00849 m_config->richText() ? "true" : "false" );
00850 }
00851
00852
00853 slotApplyConfig();
00854
00855
00856
00857 int desktop = m_config->desktop();
00858
00859 #ifdef Q_WS_X11
00860 if ( ( desktop < 0 && desktop != NETWinInfo::OnAllDesktops ) ||
00861 !m_config->rememberDesktop() )
00862 desktop = KWindowSystem::currentDesktop();
00863 #endif
00864
00865
00866 if ( desktop != 0 && !m_config->hideNote() ) {
00867
00868 toDesktop( desktop );
00869 show();
00870
00871
00872 #ifdef Q_WS_X11
00873 if ( desktop == NETWinInfo::OnAllDesktops ) {
00874 toDesktop( desktop );
00875 }
00876 #endif
00877 }
00878
00879 m_readOnly->setChecked( m_config->readOnly() );
00880 slotUpdateReadOnly();
00881
00882 if ( m_config->keepAbove() ) {
00883 m_keepAbove->setChecked( true );
00884 } else if ( m_config->keepBelow() ) {
00885 m_keepBelow->setChecked( true );
00886 } else {
00887 m_keepAbove->setChecked( false );
00888 m_keepBelow->setChecked( false );
00889 }
00890 slotUpdateKeepAboveBelow();
00891
00892
00893
00894 KIconEffect effect;
00895 QPixmap icon = effect.apply( qApp->windowIcon().pixmap(
00896 IconSize( KIconLoader::Desktop ),
00897 IconSize( KIconLoader::Desktop ) ),
00898 KIconEffect::Colorize,
00899 1, m_config->bgColor(), false );
00900 QPixmap miniIcon = effect.apply( qApp->windowIcon().pixmap(
00901 IconSize( KIconLoader::Small ),
00902 IconSize( KIconLoader::Small ) ),
00903 KIconEffect::Colorize,
00904 1, m_config->bgColor(), false );
00905 #ifdef Q_WS_X11
00906 KWindowSystem::setIcons( winId(), icon, miniIcon );
00907 #endif
00908 }
00909
00910 void KNote::toDesktop( int desktop )
00911 {
00912 if ( desktop == 0 ) {
00913 return;
00914 }
00915
00916 #ifdef Q_WS_X11
00917 if ( desktop == NETWinInfo::OnAllDesktops ) {
00918 KWindowSystem::setOnAllDesktops( winId(), true );
00919 } else {
00920 KWindowSystem::setOnDesktop( winId(), desktop );
00921 }
00922 #endif
00923 }
00924
00925 void KNote::setColor( const QColor &fg, const QColor &bg )
00926 {
00927 QPalette p = palette();
00928
00929
00930
00931
00932
00933
00934 p.setColor( QPalette::Window, bg );
00935
00936 p.setColor( QPalette::Base, bg );
00937
00938
00939 p.setColor( QPalette::WindowText, fg );
00940 p.setColor( QPalette::Text, fg );
00941
00942 p.setColor( QPalette::Button, bg.dark( 116 ) );
00943 p.setColor( QPalette::ButtonText, fg );
00944
00945
00946
00947
00948
00949
00950
00951 p.setColor( QPalette::Light, bg.light( 180 ) );
00952 p.setColor( QPalette::Midlight, bg.light( 150 ) );
00953 p.setColor( QPalette::Mid, bg.light( 150 ) );
00954 p.setColor( QPalette::Dark, bg.dark( 108 ) );
00955 p.setColor( QPalette::Shadow, bg.dark( 116 ) );
00956
00957 setPalette( p );
00958
00959
00960 p.setColor( QPalette::Active, QPalette::Base, bg.dark( 116 ) );
00961
00962 m_label->setPalette( p );
00963
00964
00965 m_editor->setTextColor( fg );
00966
00967
00968 KIconEffect effect;
00969 QPixmap icon = effect.apply( qApp->windowIcon().pixmap(
00970 IconSize( KIconLoader::Desktop ),
00971 IconSize( KIconLoader::Desktop ) ),
00972 KIconEffect::Colorize, 1, bg, false );
00973 QPixmap miniIcon = effect.apply( qApp->windowIcon().pixmap(
00974 IconSize( KIconLoader::Small ),
00975 IconSize( KIconLoader::Small ) ),
00976 KIconEffect::Colorize, 1, bg, false );
00977 #ifdef Q_WS_X11
00978 KWindowSystem::setIcons( winId(), icon, miniIcon );
00979 #endif
00980
00981 updateFocus();
00982 emit sigColorChanged();
00983 }
00984
00985 void KNote::updateLabelAlignment()
00986 {
00987
00988 QString labelText = m_label->text();
00989 if ( m_label->fontMetrics().boundingRect( labelText ).width() >
00990 m_label->width() ) {
00991 m_label->setAlignment( Qt::AlignLeft );
00992 } else {
00993 m_label->setAlignment( Qt::AlignHCenter );
00994 }
00995 }
00996
00997 void KNote::updateFocus()
00998 {
00999 if ( hasFocus() ) {
01000 m_button->show();
01001 m_grip->show();
01002
01003 if ( !m_editor->isReadOnly() ) {
01004 if ( m_tool && m_tool->isHidden() && m_editor->acceptRichText() ) {
01005 m_tool->show();
01006 setGeometry( x(), y(), width(), height() + m_tool->height() );
01007 }
01008 } else if ( m_tool && !m_tool->isHidden() ) {
01009 m_tool->hide();
01010 setGeometry( x(), y(), width(), height() - m_tool->height() );
01011 updateLayout();
01012 }
01013 } else {
01014 m_button->hide();
01015 m_grip->hide();
01016
01017 if ( m_tool && !m_tool->isHidden() ) {
01018 m_tool->hide();
01019 setGeometry( x(), y(), width(), height() - m_tool->height() );
01020 updateLayout();
01021 }
01022 }
01023 }
01024
01025 void KNote::updateLayout()
01026 {
01027
01028 updateLabelAlignment();
01029 }
01030
01031
01032
01033 void KNote::contextMenuEvent( QContextMenuEvent *e )
01034 {
01035 if ( m_menu ) {
01036 m_menu->popup( e->globalPos() );
01037 }
01038 }
01039
01040 void KNote::showEvent( QShowEvent * )
01041 {
01042 if ( m_config->hideNote() ) {
01043
01044 slotUpdateKeepAboveBelow();
01045 slotUpdateShowInTaskbar();
01046 toDesktop( m_config->desktop() );
01047 move( m_config->position() );
01048 m_config->setHideNote( false );
01049 }
01050 }
01051
01052 void KNote::resizeEvent( QResizeEvent *qre )
01053 {
01054 QFrame::resizeEvent( qre );
01055 updateLayout();
01056 }
01057
01058 void KNote::closeEvent( QCloseEvent * )
01059 {
01060 slotClose();
01061 }
01062
01063 void KNote::dragEnterEvent( QDragEnterEvent *e )
01064 {
01065 if ( !m_config->readOnly() ) {
01066 e->setAccepted( e->mimeData()->hasColor() );
01067 }
01068 }
01069
01070 void KNote::dropEvent( QDropEvent *e )
01071 {
01072 if ( m_config->readOnly() ) {
01073 return;
01074 }
01075
01076 const QMimeData *md = e->mimeData();
01077 if ( md->hasColor() ) {
01078 QColor bg = qvariant_cast<QColor>( md->colorData() );
01079 setColor( palette().color( foregroundRole() ), bg );
01080 m_journal->setCustomProperty( "KNotes", "BgColor", bg.name() );
01081 m_config->setBgColor( bg );
01082 }
01083 }
01084
01085 bool KNote::event( QEvent *ev )
01086 {
01087 if ( ev->type() == QEvent::LayoutRequest ) {
01088 updateLayout();
01089 return true;
01090 } else {
01091 return QFrame::event( ev );
01092 }
01093 }
01094
01095 bool KNote::eventFilter( QObject *o, QEvent *ev )
01096 {
01097 if ( ev->type() == QEvent::DragEnter &&
01098 static_cast<QDragEnterEvent*>( ev )->mimeData()->hasColor() ) {
01099 dragEnterEvent( static_cast<QDragEnterEvent *>( ev ) );
01100 return true;
01101 }
01102
01103 if ( ev->type() == QEvent::Drop &&
01104 static_cast<QDropEvent *>( ev )->mimeData()->hasColor() ) {
01105 dropEvent( static_cast<QDropEvent *>( ev ) );
01106 return true;
01107 }
01108
01109 if ( o == m_label ) {
01110 QMouseEvent *e = ( QMouseEvent * )ev;
01111
01112 if ( ev->type() == QEvent::MouseButtonDblClick ) {
01113 slotRename();
01114 }
01115
01116 if ( ev->type() == QEvent::MouseButtonPress &&
01117 ( e->button() == Qt::LeftButton || e->button() == Qt::MidButton ) ) {
01118 #ifdef Q_WS_X11
01119 e->button() == Qt::LeftButton ? KWindowSystem::raiseWindow( winId() )
01120 : KWindowSystem::lowerWindow( winId() );
01121
01122 XUngrabPointer( QX11Info::display(), QX11Info::appTime() );
01123 NETRootInfo wm_root( QX11Info::display(), NET::WMMoveResize );
01124 wm_root.moveResizeRequest( winId(), e->globalX(), e->globalY(),
01125 NET::Move );
01126 #endif
01127 return true;
01128 }
01129
01130 if ( ev->type() == QEvent::MouseButtonRelease ) {
01131 #ifdef Q_WS_X11
01132 NETRootInfo wm_root( QX11Info::display(), NET::WMMoveResize );
01133 wm_root.moveResizeRequest( winId(), e->globalX(), e->globalY(),
01134 NET::MoveResizeCancel );
01135 #endif
01136 return false;
01137 }
01138
01139 return false;
01140 }
01141
01142 if ( o == m_editor ) {
01143 if ( ev->type() == QEvent::FocusOut ) {
01144 QFocusEvent *fe = static_cast<QFocusEvent *>( ev );
01145 if ( fe->reason() != Qt::PopupFocusReason &&
01146 fe->reason() != Qt::MouseFocusReason ) {
01147 updateFocus();
01148 if ( isModified() ) {
01149 saveData();
01150 }
01151 }
01152 } else if ( ev->type() == QEvent::FocusIn ) {
01153 updateFocus();
01154 }
01155
01156 return false;
01157 }
01158
01159 return false;
01160 }
01161
01162
01163 #include "knote.moc"