Merge pull request #136 from sandsmark/sonnet
authorManuel Nickschas <sputnick@quassel-irc.org>
Sun, 28 Feb 2016 17:58:03 +0000 (18:58 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 28 Feb 2016 17:58:03 +0000 (18:58 +0100)
Add spell-checking support via the Sonnet framework

1  2 
CMakeLists.txt
src/qtui/CMakeLists.txt
src/qtui/mainwin.cpp
src/uisupport/multilineedit.cpp

diff --combined CMakeLists.txt
@@@ -217,21 -217,12 +217,21 @@@ if (USE_QT5
              PURPOSE     "Required for audio notifications"
          )
  
 -        find_package(LibsnoreQt5 QUIET)
 +        find_package(LibsnoreQt5 0.7.0 QUIET)
          set_package_properties(LibsnoreQt5 PROPERTIES TYPE OPTIONAL
 -            URL "https://github.com/TheOneRing/Snorenotify"
 +            URL "https://projects.kde.org/projects/playground/libs/snorenotify"
              DESCRIPTION "a cross-platform notification framework"
              PURPOSE     "Enable support for the snorenotify framework"
          )
 +        if(LibsnoreQt5_FOUND)
 +            find_package(LibsnoreSettingsQt5)
 +            set_package_properties(LibsnoreSettingsQt5 PROPERTIES TYPE REQUIRED
 +                URL "https://projects.kde.org/projects/playground/libs/snorenotify"
 +                DESCRIPTION "a cross-platform notification framework"
 +                PURPOSE     "Enable support for the snorenotify framework"
 +            )
 +        endif()
 +        
  
          if (WITH_WEBKIT)
              find_package(Qt5WebKit QUIET)
                  )
              endif()
          endif()
 -        add_feature_info("WITH_WEBKIT, QtWebKit and QtWebKitWidgets modules" Qt5WebKitWidgets_FOUND "Support showing previews for URLs in chat")
 +
 +        if (WITH_WEBKIT AND Qt5WebKitWidgets_FOUND)
 +            set(HAVE_WEBKIT true)
 +        endif()
 +        add_feature_info("WITH_WEBKIT, QtWebKit and QtWebKitWidgets modules" HAVE_WEBKIT "Support showing previews for URLs in chat")
  
          # KDE Frameworks
          ################
  
          if (ECM_FOUND)
              list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
-         endif()
-         if (WITH_KDE)
-             find_package(KF5 COMPONENTS ConfigWidgets CoreAddons Notifications NotifyConfig TextWidgets WidgetsAddons XmlGui QUIET)
-             set_package_properties(KF5 PROPERTIES TYPE REQUIRED
-                 URL "http://www.kde.org"
-                 DESCRIPTION "KDE Frameworks"
-                 PURPOSE     "Required for integration into the Plasma desktop"
-             )
-         endif()
+             if (WITH_KDE)
+                 find_package(KF5 COMPONENTS ConfigWidgets CoreAddons Notifications NotifyConfig TextWidgets WidgetsAddons XmlGui QUIET)
+                 set_package_properties(KF5 PROPERTIES TYPE REQUIRED
+                     URL "http://www.kde.org"
+                     DESCRIPTION "KDE Frameworks"
+                     PURPOSE     "Required for integration into the Plasma desktop"
+                 )
+             else(WITH_KDE)
+                 find_package(KF5Sonnet QUIET)
+                 set_package_properties(KF5Sonnet PROPERTIES TYPE RECOMMENDED
+                     URL "http://api.kde.org/frameworks-api/frameworks5-apidocs/sonnet/html"
+                     DESCRIPTION "framework for providing spell-checking capabilities"
+                     PURPOSE "Enables spell-checking support in input widgets"
+                 )
+             endif(WITH_KDE)
+         endif(ECM_FOUND)
  
      endif(BUILD_GUI)
  
@@@ -370,6 -362,13 +375,6 @@@ else(USE_QT5
                  DESCRIPTION "a multimedia abstraction library"
                  PURPOSE     "Required for audio notifications"
              )
 -
 -            find_package(Libsnore QUIET)
 -            set_package_properties(Libsnore PROPERTIES TYPE OPTIONAL
 -                URL "https://github.com/TheOneRing/Snorenotify"
 -                DESCRIPTION "a cross-platform notification framework"
 -                PURPOSE     "Enable support for the snorenotify framework"
 -            )
          endif(WITH_KDE)
  
          find_package(IndicateQt QUIET)
@@@ -422,20 -421,6 +427,20 @@@ if (NOT WIN32
      )
  endif()
  
 +# Check for SSL support in Qt
 +# As there's no easy way to get Qt's configuration in particular for Qt5, let's just compile
 +# a small test program checking the defines. This works for both Qt4 and Qt5.
 +cmake_push_check_state(RESET)
 +set(CMAKE_REQUIRED_INCLUDES ${QT_INCLUDES} ${Qt5Core_INCLUDE_DIRS})
 +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
 +check_cxx_source_compiles("
 +    #include \"qglobal.h\"
 +    #if defined QT_NO_SSL
 +    #  error \"No SSL support\"
 +    #endif
 +    int main() {}"
 +    HAVE_SSL)
 +cmake_pop_check_state()
  
  # Additional compile settings
  #####################################################################
@@@ -499,6 -484,20 +504,6 @@@ if (NOT ZLIB_FOUND
      endif()
  endif()
  
 -# Check for SSL support in Qt
 -# As there's no easy way to get Qt's configuration in particular for Qt5, let's just compile
 -# a small test program checking the defines. This works for both Qt4 and Qt5.
 -cmake_push_check_state(RESET)
 -set(CMAKE_REQUIRED_INCLUDES ${QT_INCLUDES} ${Qt5Core_INCLUDE_DIRS})
 -check_cxx_source_compiles("
 -    #include \"qglobal.h\"
 -    #if defined QT_NO_OPENSSL || defined QT_NO_SSL
 -    #  error \"No SSL support\"
 -    #endif
 -    int main() {}"
 -    HAVE_SSL)
 -cmake_pop_check_state()
 -
  if (HAVE_SSL)
      add_definitions(-DHAVE_SSL)
  endif()
@@@ -576,10 -575,10 +581,10 @@@ git_describe(GIT_DESCRIBE --long
  # enviroment
  if (NOT GIT_HEAD OR NOT GIT_DESCRIBE)
    if (DEFINED ENV{GIT_HEAD})
 -      set(GIT_HEAD ${GIT_HEAD})
 +      set(GIT_HEAD $ENV{GIT_HEAD})
    endif ()
    if (DEFINED ENV{GIT_DESCRIBE})
 -     set(GIT_DESCRIBE ${GIT_DESCRIBE})
 +     set(GIT_DESCRIBE $ENV{GIT_DESCRIBE})
    endif()
  endif()
  
diff --combined src/qtui/CMakeLists.txt
@@@ -95,11 -95,12 +95,11 @@@ if (WITH_KF5
      list(APPEND LIBS KF5::ConfigWidgets KF5::Notifications KF5::NotifyConfig KF5::WidgetsAddons KF5::XmlGui)
  endif()
  
 -if (LIBSNORE_FOUND)
 +if (LibsnoreQt5_FOUND)
      add_definitions(-DHAVE_LIBSNORE)
 -    include_directories(${LIBSNORE_INCLUDE_DIRS})
      list(APPEND SOURCES snorenotificationbackend.cpp)
      list(APPEND FORMS   snorentificationconfigwidget.ui)
 -    list(APPEND LIBS ${LIBSNORE_LIBRARIES})
 +    list(APPEND LIBS    Snore::Libsnore Snore::LibsnoreSettings)
  endif()
  
  if (PHONON_FOUND OR Phonon4Qt5_FOUND)
@@@ -129,7 -130,7 +129,7 @@@ if (QT_QTDBUS_FOUND OR Qt5DBus_FOUND
      qt_add_dbus_adaptor  (SOURCES ../../interfaces/org.kde.StatusNotifierItem.xml statusnotifieritemdbus.h StatusNotifierItemDBus)
  endif()
  
 -if (QT_QTWEBKIT_FOUND OR Qt5WebKitWidgets_FOUND)
 +if (HAVE_WEBKIT)
      add_definitions(-DHAVE_WEBKIT)
      list(APPEND QT_MODULES WebKit)
      if (USE_QT5)
@@@ -156,6 -157,12 +156,12 @@@ if (WITH_NOTIFICATION_CENTER
      list(APPEND LIBS "/System/Library/Frameworks/Foundation.framework")
  endif()
  
+ if (KF5Sonnet_FOUND)
+     add_definitions(-DHAVE_SONNET)
+     list(APPEND SOURCES settingspages/sonnetsettingspage.cpp)
+     list(APPEND LIBS KF5::SonnetUi)
+ endif()
  foreach(FORM ${FORMS})
    set(FORMPATH ${FORMPATH} ui/${FORM})
  endforeach(FORM ${FORMS})
diff --combined src/qtui/mainwin.cpp
  #  ifdef HAVE_PHONON
  #    include "phononnotificationbackend.h"
  #  endif
 -#  ifdef HAVE_LIBSNORE
 -#    include "snorenotificationbackend.h"
 -#  endif
  #  include "systraynotificationbackend.h"
  #  include "taskbarnotificationbackend.h"
  #else /* HAVE_KDE */
  #  include "knotificationbackend.h"
  #endif /* HAVE_KDE */
  
 +
 +#ifdef HAVE_LIBSNORE
 +#  include "snorenotificationbackend.h"
 +#endif
 +
  #ifdef HAVE_SSL
  #  include "sslinfodlg.h"
  #endif
  #  include "settingspages/shortcutssettingspage.h"
  #endif
  
+ #ifdef HAVE_SONNET
+ #  include "settingspages/sonnetsettingspage.h"
+ #endif
  MainWin::MainWin(QWidget *parent)
  #ifdef HAVE_KDE
      : KMainWindow(parent), _kHelpMenu(new KHelpMenu(this)),
@@@ -226,18 -229,18 +231,18 @@@ void MainWin::init(
  #  ifdef HAVE_PHONON
      QtUi::registerNotificationBackend(new PhononNotificationBackend(this));
  #  endif
 -#  ifdef HAVE_LIBSNORE
 -    QtUi::registerNotificationBackend(new SnoreNotificationBackend(this));
 -#  elif !defined(QT_NO_SYSTEMTRAYICON)
 -    QtUi::registerNotificationBackend(new SystrayNotificationBackend(this));
 -#  endif
 -
      QtUi::registerNotificationBackend(new TaskbarNotificationBackend(this));
 -
  #else /* HAVE_KDE */
      QtUi::registerNotificationBackend(new KNotificationBackend(this));
  #endif /* HAVE_KDE */
  
 +
 +#ifdef HAVE_LIBSNORE
 +    QtUi::registerNotificationBackend(new SnoreNotificationBackend(this));
 +#elif !defined(QT_NO_SYSTEMTRAYICON) && !defined(HAVE_KDE)
 +    QtUi::registerNotificationBackend(new SystrayNotificationBackend(this));
 +#endif
 +
  #ifdef HAVE_INDICATEQT
      QtUi::registerNotificationBackend(new IndicatorNotificationBackend(this));
  #endif
@@@ -879,8 -882,6 +884,8 @@@ void MainWin::setupNickWidget(
      // attach the NickListWidget to the BufferModel and the default selection
      _nickListWidget->setModel(Client::bufferModel());
      _nickListWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel());
 +
 +    _nickListWidget->setVisible(false);
  }
  
  
@@@ -1133,7 -1134,7 +1138,7 @@@ void MainWin::loadLayout(
          _layoutLoaded = true;
          return;
      }
 -
 +    _nickListWidget->setVisible(true);
      restoreState(state, accountId);
      int bufferViewId = s.value(QString("ActiveBufferView-%1").arg(accountId), -1).toInt();
      if (bufferViewId >= 0)
@@@ -1203,7 -1204,6 +1208,7 @@@ void MainWin::setDisconnectedState(
          _msgProcessorStatusWidget->setProgress(0, 0);
      updateIcon();
      systemTray()->setState(SystemTray::Passive);
 +    _nickListWidget->setVisible(false);
  }
  
  
@@@ -1367,6 -1367,9 +1372,9 @@@ void MainWin::showSettingsDlg(
      dlg->registerSettingsPage(new BufferViewSettingsPage(dlg));
      dlg->registerSettingsPage(new InputWidgetSettingsPage(dlg));
      dlg->registerSettingsPage(new TopicWidgetSettingsPage(dlg));
+ #ifdef HAVE_SONNET
+     dlg->registerSettingsPage(new SonnetSettingsPage(dlg));
+ #endif
      dlg->registerSettingsPage(new HighlightSettingsPage(dlg));
      dlg->registerSettingsPage(new NotificationsSettingsPage(dlg));
      dlg->registerSettingsPage(new BacklogSettingsPage(dlg));
   ***************************************************************************/
  
  #include <QApplication>
- #include <QMenu>
  #include <QMessageBox>
  #include <QScrollBar>
  
+ #ifdef HAVE_SONNET
+ #  include <Sonnet/SpellCheckDecorator>
+ #endif
  #include "actioncollection.h"
  #include "bufferview.h"
  #include "graphicalui.h"
@@@ -41,7 -44,6 +44,7 @@@ MultiLineEdit::MultiLineEdit(QWidget *p
      _scrollBarsEnabled(true),
      _pasteProtectionEnabled(true),
      _emacsMode(false),
 +    _completionSpace(0),
      _lastDocumentHeight(-1)
  {
      document()->setDocumentMargin(0);
      enableFindReplace(false);
  #endif
  
+ #ifdef HAVE_SONNET
+     new Sonnet::SpellCheckDecorator(this);
+ #endif
      setMode(SingleLine);
      setLineWrapEnabled(false);
      reset();
  
 +    // Prevent QTextHtmlImporter::appendNodeText from eating whitespace
 +    document()->setDefaultStyleSheet("span { white-space: pre-wrap; }");
 +
      connect(this, SIGNAL(textChanged()), this, SLOT(on_textChanged()));
  
      _mircColorMap["00"] = "#ffffff";
@@@ -671,12 -674,8 +678,12 @@@ void MultiLineEdit::on_returnPressed(
  }
  
  
 -void MultiLineEdit::on_returnPressed(const QString &text)
 +void MultiLineEdit::on_returnPressed(QString text)
  {
 +    if (_completionSpace && text.endsWith(" ")) {
 +        text.chop(1);
 +    }
 +
      if (!text.isEmpty()) {
          foreach(const QString &line, text.split('\n', QString::SkipEmptyParts)) {
              if (line.isEmpty())
  
  void MultiLineEdit::on_textChanged()
  {
 +    _completionSpace = qMax(_completionSpace - 1, 0);
 +
      QString newText = text();
      newText.replace("\r\n", "\n");
      newText.replace('\r', '\n');
@@@ -779,12 -776,3 +786,12 @@@ void MultiLineEdit::showHistoryEntry(
      setTextCursor(cursor);
      updateScrollBars();
  }
 +
 +
 +void MultiLineEdit::addCompletionSpace()
 +{
 +    // Inserting the space emits textChanged, which should not disable removal
 +    _completionSpace = 2;
 +    insertPlainText(" ");
 +}
 +