import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
+import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Vector;
import org.apache.thrift.TException;
+import org.h2.tools.ChangeFileEncryption;
import com.evernote.edam.error.EDAMNotFoundException;
import com.evernote.edam.error.EDAMSystemException;
import com.trolltech.qt.core.QDataStream;
import com.trolltech.qt.core.QDateTime;
import com.trolltech.qt.core.QDir;
+import com.trolltech.qt.core.QEvent;
import com.trolltech.qt.core.QFile;
import com.trolltech.qt.core.QFileInfo;
import com.trolltech.qt.core.QFileSystemWatcher;
import cx.fbn.nevernote.config.StartupConfig;
import cx.fbn.nevernote.dialog.AccountDialog;
import cx.fbn.nevernote.dialog.ConfigDialog;
+import cx.fbn.nevernote.dialog.DBEncryptDialog;
import cx.fbn.nevernote.dialog.DatabaseLoginDialog;
import cx.fbn.nevernote.dialog.DatabaseStatus;
import cx.fbn.nevernote.dialog.FindDialog;
TableView noteTableView; // List of notes (the widget).
public BrowserWindow browserWindow; // Window containing browser & labels
- QToolBar toolBar; // The tool bar under the menu
+ public QToolBar toolBar; // The tool bar under the menu
// QLineEdit searchField; // The search filter bar on the toolbar
QComboBox searchField; // search filter bar on the toolbar;
boolean searchPerformed = false; // Search was done?
String trashNoteGuid; // Guid to restore / set into or out of trash to save position
Thumbnailer preview; // generate preview image
ThumbnailViewer thumbnailViewer; // View preview thumbnail;
+ boolean encryptOnShutdown; // should I encrypt when I close?
+ boolean decryptOnShutdown; // should I decrypt on shutdown;
+ String encryptCipher; // What cipher should I use?
+ Signal0 minimizeToTray;
+ boolean windowMaximized = false; // Keep track of the window state for restores
String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
logger = new ApplicationLogger("nevernote.log");
logger.log(logger.HIGH, "Starting Application");
-
+
+ decryptOnShutdown = false;
+ encryptOnShutdown = false;
conn.checkDatabaseVersion();
+
+
// Start building the invalid XML tables
Global.invalidElements = conn.getInvalidXMLTable().getInvalidElements();
List<String> elements = conn.getInvalidXMLTable().getInvalidAttributeElements();
logger.log(logger.EXTREME, "Starting GUI build");
- QTranslator qtTranslator = new QTranslator();
- qtTranslator.load("classpath:/translations/qt_" + QLocale.system().name() + ".qm");
- QApplication.instance().installTranslator(qtTranslator);
-
QTranslator nevernoteTranslator = new QTranslator();
- nevernoteTranslator.load("classpath:/translations/nevernote_"+QLocale.system().name()+ ".qm");
+ nevernoteTranslator.load(Global.getFileManager().getTranslateFilePath("nevernote_" + QLocale.system().name() + ".qm"));
QApplication.instance().installTranslator(nevernoteTranslator);
Global.originalPalette = QApplication.palette();
synchronizeAnimationTimer.timeout.connect(this, "updateSyncButton()");
indexTimer = new QTimer();
- indexTime = 1000*60*5; // look for unindexed every 5 minutes
-// indexTime = 1000*5;
+ indexTime = 1000*Global.getIndexThreadSleepInterval();
indexTimer.start(indexTime); // Start indexing timer
indexTimer.timeout.connect(this, "indexTimer()");
indexDisabled = false;
NeverNote application = new NeverNote(dbConn);
application.setAttribute(WidgetAttribute.WA_DeleteOnClose, true);
- if (Global.wasWindowMaximized())
- application.showMaximized();
- else
- application.show();
+ if (Global.startMinimized())
+ application.showMinimized();
+ else {
+ if (Global.wasWindowMaximized())
+ application.showMaximized();
+ else
+ application.show();
+ }
+
if (showSplash)
splash.finish(application);
QApplication.exec();
*/
private static DatabaseConnection setupDatabaseConnection() throws InitializationException {
ApplicationLogger logger = new ApplicationLogger("nevernote-database.log");
- DatabaseConnection dbConn = new DatabaseConnection(logger,Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
-
+
+ File f = Global.getFileManager().getDbDirFile(Global.databaseName + ".h2.db");
+ boolean dbExists = f.exists();
+ if (!dbExists)
+ Global.setDatabaseUrl("");
+
if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") > -1) {
boolean goodCheck = false;
while (!goodCheck) {
Global.getDatabaseUserPassword(), Global.cipherPassword);
}
}
- return dbConn;
+ DatabaseConnection dbConn = new DatabaseConnection(logger,Global.getDatabaseUrl(), Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+ return dbConn;
}
+
+ // Encrypt the database upon shutdown
+ private void encryptOnShutdown() {
+ String dbPath= Global.getFileManager().getDbDirPath("");
+ String dbName = "NeverNote";
+ try {
+ Statement st = conn.getConnection().createStatement();
+ st.execute("shutdown");
+ if (QMessageBox.question(this, "Are you sure",
+ "Are you sure you wish to encrypt the database?",
+ QMessageBox.StandardButton.Yes,
+ QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
+ ChangeFileEncryption.execute(dbPath, dbName, encryptCipher, null, Global.cipherPassword.toCharArray(), true);
+ Global.setDatabaseUrl(Global.getDatabaseUrl() + ";CIPHER="+encryptCipher);
+ QMessageBox.information(this, "Encryption Complete", "Encryption is complete");
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Decrypt the database upon shutdown
+ private void decryptOnShutdown() {
+ String dbPath= Global.getFileManager().getDbDirPath("");
+ String dbName = "NeverNote";
+ try {
+ Statement st = conn.getConnection().createStatement();
+ st.execute("shutdown");
+ if (Global.getDatabaseUrl().toUpperCase().indexOf(";CIPHER=AES") > -1)
+ encryptCipher = "AES";
+ else
+ encryptCipher = "XTEA";
+ if (QMessageBox.question(this, tr("Confirmation"), tr("Are you sure",
+ "Are you sure you wish to decrypt the database?"),
+ QMessageBox.StandardButton.Yes,
+ QMessageBox.StandardButton.No) == StandardButton.Yes.value()) {
- private static void initializeGlobalSettings(String[] args) throws InitializationException {
- StartupConfig startupConfig = new StartupConfig();
+ ChangeFileEncryption.execute(dbPath, dbName, encryptCipher, Global.cipherPassword.toCharArray(), null, true);
+ Global.setDatabaseUrl("");
+ QMessageBox.information(this, tr("Decryption Complete"), tr("Decryption is complete"));
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ /**
+ * Encrypt/Decrypt the local database
+ **/
+ public void doDatabaseEncrypt() {
+ // The database is not currently encrypted
+ if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") == -1) {
+ if (QMessageBox.question(this, tr("Confirmation"), tr("Encrypting the database is used" +
+ "to enhance security and is performed\nupon shutdown, but please be aware that if"+
+ " you lose the password your\nis lost forever.\n\nIt is highly recommended you " +
+ "perform a backup and/or fully synchronize\n prior to executing this funtction.\n\n" +
+ "Do you wish to proceed?"),
+ QMessageBox.StandardButton.Yes,
+ QMessageBox.StandardButton.No)==StandardButton.No.value()) {
+ return;
+ }
+ DBEncryptDialog dialog = new DBEncryptDialog();
+ dialog.exec();
+ if (dialog.okPressed()) {
+ Global.cipherPassword = dialog.getPassword();
+ encryptOnShutdown = true;
+ encryptCipher = dialog.getEncryptionMethod();
+ }
+ } else {
+ DBEncryptDialog dialog = new DBEncryptDialog();
+ dialog.setWindowTitle("Database Decryption");
+ dialog.hideEncryption();
+ dialog.exec();
+ if (dialog.okPressed()) {
+ if (!dialog.getPassword().equals(Global.cipherPassword)) {
+ QMessageBox.critical(null, tr("Incorrect Password"), tr("Incorrect Password"));
+ return;
+ }
+ decryptOnShutdown = true;
+ encryptCipher = "";
+ }
+ }
+ return;
+ }
- for (String arg : args) {
- String lower = arg.toLowerCase();
- if (lower.startsWith("--name="))
- startupConfig.setName(arg.substring(arg.indexOf('=') + 1));
- if (lower.startsWith("--home="))
- startupConfig.setHomeDirPath(arg.substring(arg.indexOf('=') + 1));
- if (lower.startsWith("--disable-viewing"))
- startupConfig.setDisableViewing(true);
- }
+ private static void initializeGlobalSettings(String[] args) throws InitializationException {
+ StartupConfig startupConfig = new StartupConfig();
- Global.setup(startupConfig);
+ for (String arg : args) {
+ String lower = arg.toLowerCase();
+ if (lower.startsWith("--name="))
+ startupConfig.setName(arg.substring(arg.indexOf('=') + 1));
+ if (lower.startsWith("--home="))
+ startupConfig.setHomeDirPath(arg.substring(arg.indexOf('=') + 1));
+ if (lower.startsWith("--disable-viewing"))
+ startupConfig.setDisableViewing(true);
}
+ Global.setup(startupConfig);
+ }
// Exit point
@Override
Global.setColumnPosition("noteTableTitlePosition", position);
position = noteTableView.header.visualIndex(Global.noteTableSynchronizedPosition);
Global.setColumnPosition("noteTableSynchronizedPosition", position);
-
+
+ if (isVisible())
+ Global.saveWindowVisible("toolBar", toolBar.isVisible());
saveNoteIndexWidth();
int width = notebookTree.columnWidth(0);
}
}
+ if (encryptOnShutdown) {
+ encryptOnShutdown();
+ }
+ if (decryptOnShutdown) {
+ decryptOnShutdown();
+ }
logger.log(logger.HIGH, "Leaving NeverNote.closeEvent");
}
String dateFormat = Global.getDateFormat();
String timeFormat = Global.getTimeFormat();
+ indexTime = 1000*Global.getIndexThreadSleepInterval();
+ indexTimer.start(indexTime); // reset indexing timer
+
settings.exec();
if (Global.showTrayIcon())
trayIcon.show();
tr("<h4><center><b>NeverNote</b></center></h4><hr><center>Version ")
+Global.version
+tr("<hr></center>Evernote"
- +" Generic client.<br><br>"
+ +"An Open Source Evernote Client.<br><br>"
+"Licensed under GPL v2. <br><hr><br>"
+"Evernote is copyright 2001-2010 by Evernote Corporation<br>"
+"Jambi and QT are the licensed trademark of Nokia Corporation<br>"
+"PDFRenderer is licened under the LGPL<br>"
+ +"JTidy is copyrighted under the World Wide Web Consortium<br>"
+ +"Apache Common Utilities licensed under the Apache License Version 2.0<br>"
+"Jazzy is licened under the LGPL<br>"
- +"Java is a registered trademark of Sun Microsystems.<br><hr>"));
+ +"Java is a registered trademark of Oracle Corporation.<br><hr>"));
logger.log(logger.HIGH, "Leaving NeverNote.about");
}
// Hide the entire left hand side
searchPerformed = true;
logger.log(logger.HIGH, "Leaving NeverNote.searchFieldChanged");
}
+
// Build the window tool bar
private void setupToolBar() {
logger.log(logger.HIGH, "Entering NeverNote.setupToolBar");
- toolBar = addToolBar(tr("toolBar"));
+ toolBar = addToolBar(tr("Tool Bar"));
+ menuBar.setupToolBarVisible();
+ if (!Global.isWindowVisible("toolBar"))
+ toolBar.setVisible(false);
+ else
+ toolBar.setVisible(true);
prevButton = toolBar.addAction("Previous");
QIcon prevIcon = new QIcon(iconPath+"back.png");
hide();
} else {
show();
+ if (windowMaximized)
+ showMaximized();
+ else
+ showNormal();
raise();
}
}
String text2 = browserWindow.getContentsToEmail();
QUrl url = new QUrl("mailto:");
url.addQueryItem("subject", currentNote.getTitle());
- url.addQueryItem("body", QUrl.toPercentEncoding(text2).toString());
+// url.addQueryItem("body", QUrl.toPercentEncoding(text2).toString());
+ url.addQueryItem("body", text2);
QDesktopServices.openUrl(url);
}
/*
private void fullReindex() {
logger.log(logger.HIGH, "Entering NeverNote.fullReindex");
// If we are deleting non-trash notes
+ if (currentNote == null) return;
if (currentNote.getDeleted() == 0) {
if (QMessageBox.question(this, tr("Confirmation"), tr("This will cause all notes & attachments to be reindexed, "+
"but please be aware that depending upon the size of your database updating all these records " +
browserWindow.leftAlignAction.setVisible(Global.isEditorButtonVisible("alignLeft"));
browserWindow.centerAlignAction.setVisible(Global.isEditorButtonVisible("alignCenter"));
browserWindow.rightAlignAction.setVisible(Global.isEditorButtonVisible("alignRight"));
+ browserWindow.spellCheckAction.setVisible(Global.isEditorButtonVisible("spellCheck"));
+ browserWindow.todoAction.setVisible(Global.isEditorButtonVisible("todo"));
}
private void duplicateNote(String guid) {
- Calendar currentTime = new GregorianCalendar();
- Long l = new Long(currentTime.getTimeInMillis());
- String newGuid = new String(Long.toString(l));
-
Note oldNote = conn.getNoteTable().getNote(guid, true, true, false, false, false);
- Note newNote = oldNote.deepCopy();
- newNote.setGuid(newGuid);
List<Resource> resList = conn.getNoteTable().noteResourceTable.getNoteResources(guid, true);
+ oldNote.setContent(conn.getNoteTable().getNoteContentBinary(guid));
oldNote.setResources(resList);
duplicateNote(oldNote);
}
}
-
+ //*************************************************
+ //* Minimize to tray
+ //*************************************************
+ @Override
+ public void changeEvent(QEvent e) {
+ if (e.type() == QEvent.Type.WindowStateChange) {
+ if (isMinimized() && Global.showTrayIcon()) {
+ e.accept();
+ QTimer.singleShot(10, this, "hide()");
+ return;
+ }
+ if (isMaximized())
+ windowMaximized = true;
+ else
+ windowMaximized = false;
+ }
+ }
//*************************************************
//* Check database userid & passwords