aboutsummaryrefslogtreecommitdiff
path: root/lumina-desktop
diff options
context:
space:
mode:
authorKen Moore <ken@pcbsd.org>2015-01-20 16:22:03 -0500
committerKen Moore <ken@pcbsd.org>2015-01-20 16:22:03 -0500
commit0b7f30930be1318030b9749f352a8dec3b9c6f39 (patch)
treec0daffd4a133b241d81d2fe7e5a2c47d4b8560d8 /lumina-desktop
parentFix the detection of file extensions within lumina-open for files that have m... (diff)
downloadlumina-0b7f30930be1318030b9749f352a8dec3b9c6f39.tar.gz
lumina-0b7f30930be1318030b9749f352a8dec3b9c6f39.tar.bz2
lumina-0b7f30930be1318030b9749f352a8dec3b9c6f39.zip
Completely revamp the notepad desktop plugin so that it is now file-based instead of saving everything into the plugin settings directly. This allows it to manage generic text files as well as just the *.note files in ~/Notes.
Diffstat (limited to 'lumina-desktop')
-rw-r--r--lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp268
-rw-r--r--lumina-desktop/desktop-plugins/notepad/NotepadPlugin.h20
2 files changed, 233 insertions, 55 deletions
diff --git a/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp b/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp
index 214de63c..17372202 100644
--- a/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp
+++ b/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp
@@ -2,7 +2,10 @@
#include <LuminaXDG.h>
#include "LSession.h"
-
+#include <LuminaUtils.h>
+#include <QDir>
+#include <QFileDialog>
+#include <QInputDialog>
NotePadPlugin::NotePadPlugin(QWidget* parent, QString ID) : LDPlugin(parent, ID){
QVBoxLayout *vlay = new QVBoxLayout();
@@ -15,21 +18,32 @@ NotePadPlugin::NotePadPlugin(QWidget* parent, QString ID) : LDPlugin(parent, ID)
this->layout()->addWidget(frame);
frame->setLayout(vlay);
+ if(!QFile::exists(QDir::homePath()+"/Notes")){
+ //Create the notes directory if non-existant
+ QDir dir;
+ dir.mkpath(QDir::homePath()+"/Notes");
+ }
+ watcher = new QFileSystemWatcher(this);
+ //Always watch the notes directory for new files/changes
+ watcher->addPath(QDir::homePath()+"/Notes");
+
+ typeTimer = new QTimer(this);
+ typeTimer->setInterval(1000); // 1 second before it saves
+ typeTimer->setSingleShot(true); //compress lots of signals into a single save
+
+ updating = false;
//Setup the title bar header buttons
QHBoxLayout *hlay = new QHBoxLayout();
- next = new QToolButton(this);
- next->setAutoRaise(true);
- prev = new QToolButton(this);
- prev->setAutoRaise(true);
+ open = new QToolButton(this);
+ open->setAutoRaise(true);
add = new QToolButton(this);
add->setAutoRaise(true);
rem = new QToolButton(this);
rem->setAutoRaise(true);
- label = new QLabel(this);
- label->setAlignment(Qt::AlignCenter);
- hlay->addWidget(prev);
- hlay->addWidget(next);
- hlay->addWidget(label);
+ cnote = new QComboBox(this);
+
+ hlay->addWidget(cnote);
+ hlay->addWidget(open);
hlay->addWidget(add);
hlay->addWidget(rem);
vlay->addLayout(hlay);
@@ -37,20 +51,47 @@ NotePadPlugin::NotePadPlugin(QWidget* parent, QString ID) : LDPlugin(parent, ID)
//Setup the main text widget
edit = new QPlainTextEdit(this);
edit->setReadOnly(false);
+ edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
vlay->addWidget(edit);
- //Now setup the initial values
- cnote = this->settings->value("currentNote", 1).toInt();
- maxnote = this->settings->value("availableNotes",1).toInt();
+ //Special detection of the old notes format and conversion to the new files format
+ if( this->settings->value("availableNotes",-1).toInt() > 0){
+ qDebug() << "Converting all old desktop notes into the new file-based format (located at ~/Notes/<name>.note)";
+ int notes = this->settings->value("availableNotes",1).toInt();
+ int current = settings->value("currentNote",1).toInt();
+ for(int i=0; i<(notes+1); i++){
+ QString note = settings->value("Note-"+QString::number(i),"").toString();
+ settings->remove("Note-"+QString::number(i));
+ if(!note.isEmpty()){
+ //Save this note in the new file format
+ LUtils::writeFile(QDir::homePath()+"/Notes/Note-"+QString::number(i)+".note", note.split("\n"), true);
+ }
+ if(i==current){
+ //Convert the current note value to the new format
+ settings->setValue("currentFile", QDir::homePath()+"/Notes/Note-"+QString::number(i)+".note");
+ }
+ }
+ //Clear the old settings-based values
+ settings->remove("availableNotes");
+ settings->remove("currentNote");
+ }
+ //Now load the new file-based system for saving notes
+ settings->setValue("customFile",""); //always clear this when the plugin is initialized (only maintained per-session)
+ notesDirChanged();
+
+ //Now setup the initial values for the plugin
this->setInitialSize(200,300);
+
//Setup the button connections
- connect(next, SIGNAL(clicked()), this, SLOT(nextNote()) );
- connect(prev, SIGNAL(clicked()), this, SLOT(prevNote()) );
+ connect(open, SIGNAL(clicked()), this, SLOT(openNote()) );
connect(add, SIGNAL(clicked()), this, SLOT(newNote()) );
connect(rem, SIGNAL(clicked()), this, SLOT(remNote()) );
- connect(edit, SIGNAL(textChanged()), this, SLOT(noteChanged()) );
+ connect(edit, SIGNAL(textChanged()), this, SLOT(newTextAvailable()) );
+ connect(cnote, SIGNAL(currentIndexChanged(QString)), this, SLOT(noteChanged()) );
+ connect(typeTimer, SIGNAL(timeout()), this, SLOT(updateContents()) );
+ connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(notesDirChanged()) ); //re-load the available notes
+ connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(noteChanged()) ); //re-load the current file
QTimer::singleShot(0,this, SLOT(loadIcons()) );
- QTimer::singleShot(0,this, SLOT(updateContents()) );
}
@@ -58,54 +99,187 @@ NotePadPlugin::~NotePadPlugin(){
}
-void NotePadPlugin::nextNote(){
- cnote++;
- if(cnote>maxnote){ cnote = 1; } //go to the first
- updateContents();
-}
-void NotePadPlugin::prevNote(){
- cnote--;
- if(cnote<1){ cnote = maxnote; } //go to the last
- updateContents();
+void NotePadPlugin::openNote(){
+ //qDebug() << "Open New Note:";
+ //Prompt for a name for the new note
+ QFileDialog dlg(0, Qt::Dialog | Qt::WindowStaysOnTopHint );
+ dlg.setFileMode(QFileDialog::ExistingFile);
+ dlg.setAcceptMode(QFileDialog::AcceptOpen);
+ dlg.setNameFilters( QStringList() << tr("Note Files (*.note)") << tr("Text Files (*)"));
+ dlg.setWindowTitle(tr("Open a note file"));
+ dlg.setWindowIcon( LXDG::findIcon("document-open","") );
+ dlg.setDirectory(QDir::homePath()); //start in the home directory
+ //ensure it is centered on the current screen
+ QPoint center = QApplication::desktop()->screenGeometry(this).center();
+ dlg.move( center.x()-(dlg.width()/2), center.y()-(dlg.height()/2) );
+ dlg.show();
+ while( dlg.isVisible() ){
+ QApplication::processEvents();
+ }
+ QStringList sel = dlg.selectedFiles();
+ if(sel.isEmpty()){ return; } //cancelled
+ QString fullpath = sel.first();
+ QString name = fullpath.section("/",-1);
+ //qDebug() << " - Found Note:" << name << fullpath;
+ int index = cnote->findText(name, Qt::MatchExactly | Qt::MatchCaseSensitive);
+ if(QFile::exists(fullpath) && index <0){
+ //Alternate option of searching for the file in the list
+ index = cnote->findText(fullpath, Qt::MatchExactly | Qt::MatchCaseSensitive);
+ }
+ if(index>=0){
+ //This note already exists: just load it
+ cnote->setCurrentIndex(index);
+ }else{
+ //New note - add it to the end of the list and then load it
+ cnote->addItem(name, fullpath);
+ settings->setValue("customFile", fullpath); //save this as a custom file
+ cnote->setCurrentIndex( cnote->count()-1 );
+ QTimer::singleShot(1000, this, SLOT(notesDirChanged())); //Make sure to refresh the list (only one custom file at a time)
+ }
}
void NotePadPlugin::newNote(){
- maxnote++;
- cnote = maxnote;
- updateContents();
+ //Prompt for a name for the new note
+ //qDebug() << "Create new note";
+ QInputDialog dlg(0, Qt::Dialog | Qt::WindowStaysOnTopHint );
+ dlg.setInputMode(QInputDialog::TextInput);
+ dlg.setLabelText(tr("New Note Name:"));
+ dlg.setTextEchoMode(QLineEdit::Normal);
+ dlg.setWindowTitle(tr("Create a new note"));
+ dlg.setWindowIcon( LXDG::findIcon("document-new","") );
+ //ensure it is centered on the current screen
+ QPoint center = QApplication::desktop()->screenGeometry(this).center();
+ dlg.move( center.x()-(dlg.width()/2), center.y()-(dlg.height()/2) );
+ dlg.show();
+ while( dlg.isVisible() ){
+ QApplication::processEvents();
+ }
+ QString name = dlg.textValue();
+ if(name.isEmpty()){ return; } //cancelled
+ QString fullpath = QDir::homePath()+"/Notes/"+name;
+ if(!fullpath.endsWith(".note")){ fullpath.append(".note"); }
+ //qDebug() << " - New Note:" << name << fullpath;
+ int index = cnote->findText(name, Qt::MatchExactly | Qt::MatchCaseSensitive);
+ if(QFile::exists(fullpath) && index <0){
+ //Alternate option of searching for the file in the list
+ index = cnote->findText(fullpath, Qt::MatchExactly | Qt::MatchCaseSensitive);
+ }
+ if(index>=0){
+ //This note already exists: just load it
+ cnote->setCurrentIndex(index);
+ }else{
+ //New note - add it to the end of the list and then load it
+ cnote->addItem(name, fullpath);
+ cnote->setCurrentIndex( cnote->count()-1 );
+ }
}
void NotePadPlugin::remNote(){
- //Clear the current note
- settings->remove("Note-"+QString::number(cnote));
- //If the last note, also decrease the max number
- if(cnote==maxnote && maxnote>1){ maxnote--; }
- //Now go to the previous note
- cnote--;
- if(cnote<1){ cnote = maxnote; }
- updateContents();
+ QString note = cnote->currentData().toString();
+ if(note.isEmpty()){ return; }
+ watcher->removePath(note); //remove this file from the watcher
+ settings->setValue("currentFile",""); //reset the internal value
+ QFile::remove(note); //remove the file
+ //if(!note.startsWith(QDir::homePath()+"/Notes/") ){
+ //If the file was not in the notes directory, need to manually prompt for a re-load
+ // otherwise, the directory watcher will catch it and trigger a re-load (no need to double-load)
+ notesDirChanged();
+ //}
+}
+
+void NotePadPlugin::newTextAvailable(){
+ if(updating){ return; } //programmatic change of the widget
+ if(typeTimer->isActive()){ typeTimer->stop(); }
+ typeTimer->start();
}
void NotePadPlugin::updateContents(){
- next->setEnabled(cnote<maxnote);
- prev->setEnabled(cnote>1);
- label->setText( QString(tr("Note #%1")).arg(QString::number(cnote)) );
- settings->setValue("currentNote", cnote);
- settings->setValue("availableNotes", maxnote);
- edit->setPlainText( settings->value("Note-"+QString::number(cnote), "").toString() );
+ if(updating){ return; } //this was a programmatic change to the widget
+ //The text was changed in the plugin - save it in the file
+ QString note = cnote->currentData().toString();
+ updating = true;
+ LUtils::writeFile(note, edit->toPlainText().split("\n"), true);
+ updating = false;
}
+void NotePadPlugin::notesDirChanged(){
+ QString cfile = settings->value("currentFile","").toString();
+ QStringList notes;
+ QDir dir(QDir::homePath()+"/Notes");
+ QStringList files = dir.entryList(QStringList() << "*.note", QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
+ for(int i=0; i<files.length(); i++){
+ notes << dir.absoluteFilePath(files[i]);
+ }
+ QString custom = settings->value("customFile","").toString();
+ if(!custom.isEmpty() && QFile::exists(custom) ){ notes << custom; }
+ //qDebug() << "Available Notes:" << notes << cfile;
+ //Now update the UI list
+ updating = true; //don't refresh the UI until done changing lists
+ cnote->clear();
+ bool found = false;
+ for(int i=0; i<notes.length(); i++){
+ QString name = notes[i].section("/",-1);
+ if(name.endsWith(".note")){ name.chop(5); }
+ cnote->addItem(name, notes[i]);
+ if(notes[i]==cfile){ cnote->setCurrentIndex(i); found = true;}
+ }
+ if(!found && !cfile.isEmpty()){
+ //Current note is a manually-loaded text file
+ cnote->addItem(cfile.section("/",-1), cfile);
+ cnote->setCurrentIndex( cnote->count()-1 ); //last item
+ found = true;
+ }
+ if(!found && cnote->count()>0){ cnote->setCurrentIndex(0); }
+ updating =false;
+ noteChanged();
+}
void NotePadPlugin::noteChanged(){
- //Save the current text
- settings->setValue("Note-"+QString::number(cnote), edit->toPlainText());
+ if(updating){ return; }
+ updating =true;
+ QString note;
+ if(cnote->currentIndex()>=0){
+ note = cnote->currentData().toString();
+ }
+ if(note.isEmpty() && cnote->count()>0){
+ updating=false;
+ cnote->setCurrentIndex(0);
+ return;
+ }
+ QString oldnote = settings->value("currentFile","").toString();
+ //qDebug() << "Note Changed:" << note << oldnote;
+ if( oldnote!=note ){
+ //Clear the old note file/setting
+ if(!oldnote.isEmpty()){
+ watcher->removePath(oldnote);
+ settings->setValue("currentFile","");
+ }
+ if(!note.isEmpty()){
+ settings->setValue("currentFile",note);
+ watcher->addPath(note);
+ }
+ }
+
+ if(!note.isEmpty()){
+ QString text = LUtils::readFile(note).join("\n");
+ if(text!=edit->toPlainText()){
+ edit->setPlainText( text );
+ }
+ }else{
+ edit->clear();
+ }
+ //If no notes available - disable the editor until a new one is created
+ edit->setEnabled(!note.isEmpty());
+ rem->setEnabled(!note.isEmpty());
+ cnote->setEnabled(!note.isEmpty());
+ //leave the new/open buttons enabled all the time
+ updating = false;
}
void NotePadPlugin::loadIcons(){
- next->setIcon( LXDG::findIcon("go-next-view","") );
- prev->setIcon( LXDG::findIcon("go-previous-view","") );
+ open->setIcon( LXDG::findIcon("document-open","") );
add->setIcon( LXDG::findIcon("document-new","") );
rem->setIcon( LXDG::findIcon("document-close","") );
}
diff --git a/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.h b/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.h
index 0a4311ed..a1d9bf8f 100644
--- a/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.h
+++ b/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.h
@@ -11,9 +11,10 @@
#include <QPlainTextEdit>
#include <QToolButton>
-#include <QLabel>
+#include <QComboBox>
#include <QVBoxLayout>
#include <QTimer>
+#include <QFileSystemWatcher>
#include "../LDPlugin.h"
class NotePadPlugin : public LDPlugin{
@@ -24,25 +25,28 @@ public:
private:
QPlainTextEdit *edit;
- QToolButton *next, *prev, *add, *rem;
- QLabel *label;
+ QToolButton *open, *add, *rem;
+ QComboBox *cnote;
QFrame *frame;
- int cnote, maxnote; //current/max note
-
+ QFileSystemWatcher *watcher;
+ bool updating;
+ QTimer *typeTimer;
+
private slots:
- void nextNote();
- void prevNote();
+ void openNote();
void newNote();
void remNote();
+ void newTextAvailable();
void updateContents();
+ void notesDirChanged();
void noteChanged();
void loadIcons();
public slots:
void LocaleChange(){
- QTimer::singleShot(0,this, SLOT(updateContents()));
+ QTimer::singleShot(0,this, SLOT(noteChanged()));
}
void ThemeChange(){
QTimer::singleShot(0,this, SLOT(loadIcons()));
bgstack15