diff --git a/src/dialog/vselectdialog.cpp b/src/dialog/vselectdialog.cpp new file mode 100644 index 00000000..018f82ff --- /dev/null +++ b/src/dialog/vselectdialog.cpp @@ -0,0 +1,54 @@ +#include +#include "vselectdialog.h" + +VSelectDialog::VSelectDialog(const QString &p_title, QWidget *p_parent) + : QDialog(p_parent), m_choice(-1) +{ + setupUI(p_title); +} + +void VSelectDialog::setupUI(const QString &p_title) +{ + m_mainLayout = new QVBoxLayout(); + + QPushButton *cancelBtn = new QPushButton(tr("Cancel")); + cancelBtn->setProperty("SelectionBtn", true); + connect(cancelBtn, &QPushButton::clicked, + this, &VSelectDialog::reject); + m_mainLayout->addWidget(cancelBtn); + + setLayout(m_mainLayout); + m_mainLayout->setSizeConstraint(QLayout::SetFixedSize); + setWindowTitle(p_title); +} + +void VSelectDialog::addSelection(const QString &p_selectStr, int p_selectID) +{ + Q_ASSERT(p_selectID >= 0); + + QPushButton *btn = new QPushButton(p_selectStr); + btn->setProperty("SelectionBtn", true); + if (m_selections.isEmpty()) { + btn->setDefault(true); + btn->setAutoDefault(true); + } + connect(btn, &QPushButton::clicked, + this, &VSelectDialog::selectionChosen); + m_selections.insert(btn, p_selectID); + m_mainLayout->insertWidget(m_selections.size() - 1, btn); +} + +void VSelectDialog::selectionChosen() +{ + QPushButton *btn = dynamic_cast(sender()); + Q_ASSERT(btn); + auto it = m_selections.find(btn); + Q_ASSERT(it != m_selections.end()); + m_choice = *it; + accept(); +} + +int VSelectDialog::getSelection() const +{ + return m_choice; +} diff --git a/src/dialog/vselectdialog.h b/src/dialog/vselectdialog.h new file mode 100644 index 00000000..93206ab9 --- /dev/null +++ b/src/dialog/vselectdialog.h @@ -0,0 +1,31 @@ +#ifndef VSELECTDIALOG_H +#define VSELECTDIALOG_H + +#include +#include + +class QPushButton; +class QVBoxLayout; +class QMouseEvent; + +class VSelectDialog : public QDialog +{ + Q_OBJECT +public: + VSelectDialog(const QString &p_title, QWidget *p_parent = 0); + + void addSelection(const QString &p_selectStr, int p_selectID); + int getSelection() const; + +private slots: + void selectionChosen(); + +private: + void setupUI(const QString &p_title); + + QVBoxLayout *m_mainLayout; + int m_choice; + QMap m_selections; +}; + +#endif // VSELECTDIALOG_H diff --git a/src/resources/vnote.qss b/src/resources/vnote.qss index a95102e2..e43b4350 100644 --- a/src/resources/vnote.qss +++ b/src/resources/vnote.qss @@ -13,6 +13,10 @@ QPushButton[CornerBtn="true"]::hover { background-color: @hover-color; } +QPushButton[CornerBtn="true"]::focus { + background-color: @focus-color; +} + QPushButton[FlatBtn="true"] { padding: 4px; margin: 0px; @@ -24,6 +28,26 @@ QPushButton[FlatBtn="true"]::hover { background-color: @hover-color; } +QPushButton[FlatBtn="true"]::focus { + background-color: @focus-color; +} + +QPushButton[SelectionBtn="true"] { + padding: 4px 10px 4px 10px; + border: none; + background-color: transparent; + font-size: 18px; + text-align: left; +} + +QPushButton[SelectionBtn="true"]::hover { + background-color: @hover-color; +} + +QPushButton[SelectionBtn="true"]::focus { + background-color: @focus-color; +} + QPushButton[TitleBtn="true"] { padding: 4px; margin: 0px; @@ -35,6 +59,10 @@ QPushButton[TitleBtn="true"]::hover { background-color: @hover-color; } +QPushButton[TitleBtn="true"]::focus { + background-color: @focus-color; +} + QToolBar { border: none; } diff --git a/src/src.pro b/src/src.pro index 3d870461..062aa9b7 100644 --- a/src/src.pro +++ b/src/src.pro @@ -54,7 +54,8 @@ SOURCES += main.cpp\ vmdedit.cpp \ dialog/vfindreplacedialog.cpp \ dialog/vsettingsdialog.cpp \ - dialog/vdeletenotebookdialog.cpp + dialog/vdeletenotebookdialog.cpp \ + dialog/vselectdialog.cpp HEADERS += vmainwindow.h \ vdirectorytree.h \ @@ -94,7 +95,8 @@ HEADERS += vmainwindow.h \ vmdedit.h \ dialog/vfindreplacedialog.h \ dialog/vsettingsdialog.h \ - dialog/vdeletenotebookdialog.h + dialog/vdeletenotebookdialog.h \ + dialog/vselectdialog.h RESOURCES += \ vnote.qrc \ diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp index c15a7c45..509c5d3d 100644 --- a/src/utils/vutils.cpp +++ b/src/utils/vutils.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include const QVector> VUtils::c_availableLanguages = {QPair("en_US", "Englisth(US)"), QPair("zh_CN", "Chinese")}; @@ -321,3 +323,20 @@ bool VUtils::isValidLanguage(const QString &p_lang) } return false; } + +bool VUtils::isImageURL(const QUrl &p_url) +{ + QString urlStr; + if (p_url.isLocalFile()) { + urlStr = p_url.toLocalFile(); + } else { + urlStr = p_url.toString(); + } + return isImageURLText(urlStr); +} + +bool VUtils::isImageURLText(const QString &p_url) +{ + QFileInfo info(p_url); + return QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1()); +} diff --git a/src/utils/vutils.h b/src/utils/vutils.h index aa49cc96..2e288213 100644 --- a/src/utils/vutils.h +++ b/src/utils/vutils.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "vconfigmanager.h" #include "vconstants.h" @@ -37,6 +38,8 @@ public: QMessageBox::StandardButton p_defaultBtn, QWidget *p_parent); static const QVector > &getAvailableLanguages(); static bool isValidLanguage(const QString &p_lang); + static bool isImageURL(const QUrl &p_url); + static bool isImageURLText(const QString &p_url); private: // diff --git a/src/veditoperations.h b/src/veditoperations.h index f78f6dd8..da7bf9e7 100644 --- a/src/veditoperations.h +++ b/src/veditoperations.h @@ -20,8 +20,8 @@ public: VEditOperations(VEdit *p_editor, VFile *p_file); virtual ~VEditOperations(); virtual bool insertImageFromMimeData(const QMimeData *source) = 0; - virtual bool insertURLFromMimeData(const QMimeData *source) = 0; virtual bool insertImage() = 0; + virtual bool insertImageFromURL(const QUrl &p_imageUrl) = 0; // Return true if @p_event has been handled and no need to be further // processed. virtual bool handleKeyPressEvent(QKeyEvent *p_event) = 0; diff --git a/src/vmdedit.cpp b/src/vmdedit.cpp index 7c65f94a..9bb5a611 100644 --- a/src/vmdedit.cpp +++ b/src/vmdedit.cpp @@ -6,6 +6,7 @@ #include "vconfigmanager.h" #include "vtoc.h" #include "utils/vutils.h" +#include "dialog/vselectdialog.h" extern VConfigManager vconfig; extern VNote *g_vnote; @@ -106,18 +107,62 @@ bool VMdEdit::canInsertFromMimeData(const QMimeData *source) const void VMdEdit::insertFromMimeData(const QMimeData *source) { + VSelectDialog dialog(tr("Insert From Clipboard"), this); + dialog.addSelection(tr("Insert As Image"), 0); + dialog.addSelection(tr("Insert As Text"), 1); + if (source->hasImage()) { // Image data in the clipboard - bool ret = m_editOps->insertImageFromMimeData(source); - if (ret) { - return; + if (source->hasText()) { + if (dialog.exec() == QDialog::Accepted) { + if (dialog.getSelection() == 1) { + // Insert as text. + Q_ASSERT(source->hasText() && source->hasImage()); + VEdit::insertFromMimeData(source); + return; + } + } else { + return; + } } + m_editOps->insertImageFromMimeData(source); + return; } else if (source->hasUrls()) { - // Paste an image file - bool ret = m_editOps->insertURLFromMimeData(source); - if (ret) { - return; + QList urls = source->urls(); + if (urls.size() == 1 && VUtils::isImageURL(urls[0])) { + if (dialog.exec() == QDialog::Accepted) { + // FIXME: After calling dialog.exec(), source->hasUrl() returns false. + if (dialog.getSelection() == 0) { + // Insert as image. + m_editOps->insertImageFromURL(urls[0]); + return; + } + QMimeData newSource; + newSource.setUrls(urls); + VEdit::insertFromMimeData(&newSource); + return; + } else { + return; + } } + } else if (source->hasText()) { + QString text = source->text(); + if (VUtils::isImageURLText(text)) { + // The text is a URL to an image. + if (dialog.exec() == QDialog::Accepted) { + if (dialog.getSelection() == 0) { + // Insert as image. + QUrl url(text); + if (url.isValid()) { + m_editOps->insertImageFromURL(QUrl(text)); + } + return; + } + } else { + return; + } + } + Q_ASSERT(source->hasText()); } VEdit::insertFromMimeData(source); } diff --git a/src/vmdeditoperations.cpp b/src/vmdeditoperations.cpp index ed49df1c..d57cdc94 100644 --- a/src/vmdeditoperations.cpp +++ b/src/vmdeditoperations.cpp @@ -14,6 +14,7 @@ #include #include "vmdeditoperations.h" #include "dialog/vinsertimagedialog.h" +#include "dialog/vselectdialog.h" #include "utils/vutils.h" #include "vedit.h" #include "vdownloader.h" @@ -143,29 +144,6 @@ bool VMdEditOperations::insertImageFromURL(const QUrl &imageUrl) return true; } -bool VMdEditOperations::insertURLFromMimeData(const QMimeData *source) -{ - QList urls = source->urls(); - if (urls.size() != 1) { - return false; - } - QUrl url = urls.at(0); - QString urlStr; - if (url.isLocalFile()) { - urlStr = url.toLocalFile(); - } else { - urlStr = url.toString(); - } - QFileInfo info(urlStr); - if (QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1())) { - insertImageFromURL(url); - } else { - // urlStr will contain extra %0A. Let the base method handle. - return false; - } - return true; -} - bool VMdEditOperations::insertImage() { VInsertImageDialog dialog(tr("Insert Image From File"), diff --git a/src/vmdeditoperations.h b/src/vmdeditoperations.h index 57d8c1d7..bc7f26b9 100644 --- a/src/vmdeditoperations.h +++ b/src/vmdeditoperations.h @@ -16,15 +16,14 @@ class VMdEditOperations : public VEditOperations public: VMdEditOperations(VEdit *p_editor, VFile *p_file); bool insertImageFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE; - bool insertURLFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE; bool insertImage() Q_DECL_OVERRIDE; bool handleKeyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; + bool insertImageFromURL(const QUrl &p_imageUrl) Q_DECL_OVERRIDE; private slots: void pendingTimerTimeout(); private: - bool insertImageFromURL(const QUrl &imageUrl); void insertImageFromPath(const QString &title, const QString &path, const QString &oriImagePath); void insertImageFromQImage(const QString &title, const QString &path, const QImage &image); void setKeyState(KeyState p_state); diff --git a/src/vnote.cpp b/src/vnote.cpp index 648a5449..5b20f1a5 100644 --- a/src/vnote.cpp +++ b/src/vnote.cpp @@ -31,6 +31,10 @@ void VNote::initPalette(QPalette palette) palette.background().color().name())); m_palette.append(QPair("hover-color", "#42A5F5")); m_palette.append(QPair("base-color", "#BDBDBD")); + m_palette.append(QPair("focus-color", "#15AE67")); + m_palette.append(QPair("logo-base", "#D6EACE")); + m_palette.append(QPair("logo-max", "#15AE67")); + m_palette.append(QPair("logo-min", "#75C5B5")); // Material Design Colors m_palette.append(QPair("Teal0", "#E0F2F1"));