Compare commits
2 Commits
v2.0.0-bet
...
v1.0.1
Author | SHA1 | Date | |
---|---|---|---|
9c35bf150f | |||
739421c31a |
4
dist/arch/PKGBUILD
vendored
4
dist/arch/PKGBUILD
vendored
@ -1,7 +1,7 @@
|
||||
# Maintainer: Kostas Karanikolas <lastname[at]gmail[dot]com>
|
||||
pkgname=fuel
|
||||
pkgver=1.0.0
|
||||
pkgrel=3
|
||||
pkgver=1.0.1
|
||||
pkgrel=1
|
||||
pkgdesc="A GUI front-end to Fossil SCM"
|
||||
arch=(i686 x86_64)
|
||||
url="https://fuel-scm.org/"
|
||||
|
@ -1,37 +1,5 @@
|
||||
Changes
|
||||
================================================================================
|
||||
|
||||
Fuel V2.0.0 (2015-XX-XX)
|
||||
--------------------------------------------------------------------------------
|
||||
- Feature: New workspace view to visualise branches, tags, stashes and remotes
|
||||
- Feature: Support for creating, merging and integrating branches
|
||||
- Feature: Support for creating and deleting tags
|
||||
- Feature: Support for updating the workspace to a particular revisions including
|
||||
specific branches or tags
|
||||
- Feature: Support for creating a branch during commit, including private branches
|
||||
- Feature: Added Search Box for filtering and searching within the list of files
|
||||
- Feature: Display the active tags and branches in the status bar
|
||||
- Feature: Fuel now automatically detects the http port of "fossil ui"
|
||||
- Feature: Added menu shortcut to display only the modified files of the workspace
|
||||
- Feature: Support for arbitrary number of remote urls, including pushing and
|
||||
pulling to specific remotes.
|
||||
- Feature: Remote URL credentials are stored in the user keychain for systems that
|
||||
support one. Thanks to the QtKeychain project (https://github.com/frankosterfeld/qtkeychain)
|
||||
- Feature: Folders now have different appereance depending on the modification
|
||||
status of their contents, including missing folders
|
||||
- Feature: Support for multiple file user-actions
|
||||
- Feature: Double-Click action also allows user actions
|
||||
- Feature: Support for the versionable .fossil-settings/ignore-glob
|
||||
- Feature: OSX: UI improvements
|
||||
- Feature: OSX: Improved external application selection for application bundles
|
||||
- Misc: Reorganised menu structure.
|
||||
- Misc: Separated Fuel and Fossil settings
|
||||
- Bug Fix: Retain the folder tree state when refreshing the workspace
|
||||
- Bug Fix: Fixed issue with the expanding width of the commit dialog
|
||||
- Major internal refactoring
|
||||
|
||||
Fuel V1.0.1 (2015-08-23)
|
||||
--------------------------------------------------------------------------------
|
||||
================================================================================
|
||||
- Added Localisations:
|
||||
- Italian (Thanks maxxlupi and Zangune)
|
||||
- Dutch (Thanks Rick Van Lieshout and Fly Man)
|
||||
@ -39,7 +7,7 @@ Fuel V1.0.1 (2015-08-23)
|
||||
- Reformated Docs into Markdown
|
||||
|
||||
Fuel V1.0.0 (2015-03-28)
|
||||
--------------------------------------------------------------------------------
|
||||
================================================================================
|
||||
- Feature: Long Operations can now be aborted by pressing the Escape key
|
||||
- Improvement: Better support for commit messages with international characters
|
||||
- Improvement: Fossil queries about CR/NL inconsistencies are now handled better
|
||||
@ -49,7 +17,7 @@ Fuel V1.0.0 (2015-03-28)
|
||||
- Portuguese (Thanks emansije)
|
||||
|
||||
Fuel V0.9.7 (Unreleased)
|
||||
--------------------------------------------------------------------------------
|
||||
================================================================================
|
||||
- Feature: Optionally use the internal browser for the Fossil UI
|
||||
- Feature: Support for persisting the state (Column order and sizes) of the File View
|
||||
- Feature: Dropping a Fossil checkout file or workspace folder on Fuel now opens that workspace
|
||||
@ -66,7 +34,7 @@ Fuel V0.9.7 (Unreleased)
|
||||
- Distribution: Fuel is now available in the Arch User Repository
|
||||
|
||||
Fuel V0.9.6 (2012-05-13)
|
||||
--------------------------------------------------------------------------------
|
||||
================================================================================
|
||||
- Feature: Support for fossil stashes
|
||||
- Feature: Support for dragging and dropping files out of Fuel
|
||||
- Feature: Allow for opening workspaces via the checkout file or a workspace folder
|
||||
|
@ -1,195 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(qtkeychain)
|
||||
|
||||
###
|
||||
|
||||
set(QTKEYCHAIN_VERSION 0.5.90)
|
||||
set(QTKEYCHAIN_SOVERSION 0)
|
||||
|
||||
###
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${PROJECT_SOURCE_DIR}/cmake/Modules")
|
||||
include(GNUInstallDirs)
|
||||
|
||||
option(BUILD_WITH_QT4 "Build qtkeychain with Qt4 no matter if Qt5 was found" OFF)
|
||||
|
||||
|
||||
if( NOT BUILD_WITH_QT4 )
|
||||
# try Qt5 first, and prefer that if found
|
||||
find_package(Qt5Core QUIET)
|
||||
endif()
|
||||
|
||||
if (Qt5Core_FOUND)
|
||||
set(QTKEYCHAIN_VERSION_INFIX 5)
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Qt5DBus REQUIRED)
|
||||
include_directories(${Qt5DBus_INCLUDE_DIRS})
|
||||
set(QTDBUS_LIBRARIES ${Qt5DBus_LIBRARIES})
|
||||
macro(qt_add_dbus_interface)
|
||||
qt5_add_dbus_interface(${ARGN})
|
||||
endmacro()
|
||||
endif()
|
||||
find_package(Qt5LinguistTools REQUIRED)
|
||||
macro(qt_add_translation)
|
||||
qt5_add_translation(${ARGN})
|
||||
endmacro(qt_add_translation)
|
||||
macro(qt_create_translation)
|
||||
qt5_create_translation(${ARGN})
|
||||
endmacro(qt_create_translation)
|
||||
macro(qt_wrap_cpp)
|
||||
qt5_wrap_cpp(${ARGN})
|
||||
endmacro()
|
||||
|
||||
set(QTCORE_LIBRARIES ${Qt5Core_LIBRARIES})
|
||||
include_directories(${Qt5Core_INCLUDE_DIRS})
|
||||
|
||||
if (Qt5_POSITION_INDEPENDENT_CODE)
|
||||
if (CMAKE_VERSION VERSION_LESS 2.8.9) # TODO remove once we increase the cmake requirement
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
else()
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
set(QTKEYCHAIN_VERSION_INFIX "")
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Qt4 COMPONENTS QtCore QtDBus REQUIRED)
|
||||
set(QTDBUS_LIBRARIES ${QT_QTDBUS_LIBRARY})
|
||||
macro(qt_add_dbus_interface)
|
||||
qt4_add_dbus_interface(${ARGN})
|
||||
endmacro()
|
||||
else()
|
||||
find_package(Qt4 COMPONENTS QtCore REQUIRED)
|
||||
endif()
|
||||
include_directories(${QT_INCLUDES})
|
||||
set(QTCORE_LIBRARIES ${QT_QTCORE_LIBRARY})
|
||||
macro(qt_add_translation)
|
||||
qt4_add_translation(${ARGN})
|
||||
endmacro(qt_add_translation)
|
||||
macro(qt_create_translation)
|
||||
qt4_create_translation(${ARGN})
|
||||
endmacro(qt_create_translation)
|
||||
macro(qt_wrap_cpp)
|
||||
qt4_wrap_cpp(${ARGN})
|
||||
endmacro()
|
||||
endif()
|
||||
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
list(APPEND qtkeychain_LIBRARIES ${QTCORE_LIBRARIES})
|
||||
set(qtkeychain_SOURCES
|
||||
keychain.cpp
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS( -Wall )
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND qtkeychain_SOURCES keychain_win.cpp)
|
||||
list(APPEND qtkeychain_LIBRARIES crypt32)
|
||||
#FIXME: mingw bug; otherwise getting undefined refs to RtlSecureZeroMemory there
|
||||
if(MINGW)
|
||||
add_definitions( -O2 )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND qtkeychain_SOURCES keychain_mac.cpp)
|
||||
|
||||
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
list(APPEND qtkeychain_LIBRARIES ${COREFOUNDATION_LIBRARY})
|
||||
|
||||
find_library(SECURITY_LIBRARY Security)
|
||||
list(APPEND qtkeychain_LIBRARIES ${SECURITY_LIBRARY})
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
list(APPEND qtkeychain_SOURCES keychain_unix.cpp gnomekeyring.cpp)
|
||||
qt_add_dbus_interface(qtkeychain_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.KWallet.xml kwallet_interface KWalletInterface)
|
||||
list(APPEND qtkeychain_LIBRARIES ${QTDBUS_LIBRARIES})
|
||||
endif()
|
||||
|
||||
QT_WRAP_CPP(qtkeychain_MOC_OUTFILES keychain.h keychain_p.h)
|
||||
|
||||
set(qtkeychain_TR_FILES
|
||||
translations/qtkeychain_de.ts
|
||||
translations/qtkeychain_ro.ts
|
||||
)
|
||||
|
||||
file(GLOB qtkeychain_TR_SOURCES *.cpp *.h *.ui)
|
||||
qt_create_translation(qtkeychain_MESSAGES ${qtkeychain_TR_SOURCES} ${qtkeychain_TR_FILES})
|
||||
qt_add_translation(qtkeychain_QM_FILES ${qtkeychain_TR_FILES})
|
||||
add_custom_target(messages DEPENDS ${qtkeychain_MESSAGES})
|
||||
add_custom_target(translations DEPENDS ${qtkeychain_QM_FILES})
|
||||
|
||||
if(NOT QT_TRANSLATIONS_DIR)
|
||||
# If this directory is missing, we are in a Qt5 environment.
|
||||
# Extract the qmake executable location
|
||||
get_target_property(QT5_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
|
||||
# Ask Qt5 where to put the translations
|
||||
execute_process( COMMAND ${QT5_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
|
||||
OUTPUT_VARIABLE qt_translations_dir OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
# make sure we have / and not \ as qmake gives on windows
|
||||
FILE(TO_CMAKE_PATH "${qt_translations_dir}" qt_translations_dir)
|
||||
SET(QT_TRANSLATIONS_DIR ${qt_translations_dir} CACHE PATH "The
|
||||
location of the Qt translations" FORCE)
|
||||
endif()
|
||||
|
||||
install(FILES ${qtkeychain_QM_FILES}
|
||||
DESTINATION ${QT_TRANSLATIONS_DIR})
|
||||
|
||||
set(QTKEYCHAIN_TARGET_NAME qt${QTKEYCHAIN_VERSION_INFIX}keychain)
|
||||
if(NOT QTKEYCHAIN_STATIC)
|
||||
add_library(${QTKEYCHAIN_TARGET_NAME} SHARED ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES} ${qtkeychain_QM_FILES})
|
||||
set_target_properties(${QTKEYCHAIN_TARGET_NAME} PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_BUILD_QKEYCHAIN_LIB)
|
||||
target_link_libraries(${QTKEYCHAIN_TARGET_NAME} ${qtkeychain_LIBRARIES})
|
||||
else()
|
||||
add_library(${QTKEYCHAIN_TARGET_NAME} STATIC ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES} ${qtkeychain_QM_FILES})
|
||||
set_target_properties(${QTKEYCHAIN_TARGET_NAME} PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_STATICLIB)
|
||||
endif()
|
||||
|
||||
set_target_properties(${QTKEYCHAIN_TARGET_NAME} PROPERTIES
|
||||
VERSION ${QTKEYCHAIN_VERSION}
|
||||
SOVERSION ${QTKEYCHAIN_SOVERSION}
|
||||
MACOSX_RPATH 1
|
||||
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}"
|
||||
)
|
||||
|
||||
install(FILES keychain.h qkeychain_export.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/qt${QTKEYCHAIN_VERSION_INFIX}keychain/
|
||||
)
|
||||
|
||||
install(TARGETS ${QTKEYCHAIN_TARGET_NAME}
|
||||
EXPORT Qt${QTKEYCHAIN_VERSION_INFIX}KeychainLibraryDepends
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
add_executable( testclient testclient.cpp )
|
||||
target_link_libraries( testclient ${QTKEYCHAIN_TARGET_NAME})
|
||||
|
||||
|
||||
###
|
||||
### CMake config file
|
||||
###
|
||||
|
||||
export(TARGETS ${QTKEYCHAIN_TARGET_NAME} FILE "${PROJECT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainLibraryDepends.cmake")
|
||||
export(PACKAGE Qt${QTKEYCHAIN_VERSION_INFIX}Keychain)
|
||||
|
||||
configure_file(QtKeychainBuildTreeSettings.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainBuildTreeSettings.cmake" @ONLY)
|
||||
configure_file(QtKeychainConfig.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfig.cmake" @ONLY)
|
||||
configure_file(QtKeychainConfigVersion.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfigVersion.cmake" @ONLY)
|
||||
|
||||
install(EXPORT Qt${QTKEYCHAIN_VERSION_INFIX}KeychainLibraryDepends
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Qt${QTKEYCHAIN_VERSION_INFIX}Keychain"
|
||||
)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfig.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Qt${QTKEYCHAIN_VERSION_INFIX}Keychain
|
||||
)
|
||||
|
@ -1,20 +0,0 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,23 +0,0 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
version 0.5.0 (release 2015-05-04)
|
||||
* Added support for KWallet5 (KDE5/KF)
|
||||
|
||||
version 0.4.0 (release 2014-09-01)
|
||||
* KWallet: Handle case where no wallet exists yet (Liviu Cristian Mirea Ghiban <contact@liviucmg.com>)
|
||||
* Improved desktop environment detection at runtime (Daniel Molkentin <daniel@molkentin.de>)
|
||||
|
||||
version 0.3.0 (release 2014-03-13)
|
||||
* Gnome Keyring supported added (Francois Ferrand <thetypz@gmail.com>)
|
||||
* Improved Qt 5 support
|
||||
* KWallet: Distinguish empty passwords from non-existing entries
|
||||
* KWallet: Do not use hardcoded wallet name
|
||||
* German translation (Daniel Molkentin <daniel@molkentin.de>)
|
||||
* Romanian translation (Arthur Țițeică <arthur@psw.ro>)
|
||||
|
||||
version 0.2.0: no official release
|
||||
|
||||
version 0.1.0 (release 2013-01-16)
|
||||
* Initial release
|
||||
|
@ -1,4 +0,0 @@
|
||||
set(QTKEYCHAIN_INCLUDE_DIRS
|
||||
"@PROJECT_SOURCE_DIR@"
|
||||
"@PROJECT_BINARY_DIR@"
|
||||
)
|
@ -1,21 +0,0 @@
|
||||
# - Config file for the QtKeychain package
|
||||
# It defines the following variables
|
||||
# QTKEYCHAIN_INCLUDE_DIRS - include directories for QtKeychain
|
||||
# QTKEYCHAIN_LIBRARIES - libraries to link against
|
||||
|
||||
# Compute paths
|
||||
get_filename_component(QTKEYCHAIN_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
if(EXISTS "${QTKEYCHAIN_CMAKE_DIR}/CMakeCache.txt")
|
||||
# In build tree
|
||||
include("${QTKEYCHAIN_CMAKE_DIR}/Qt@QTKEYCHAIN_VERSION_INFIX@KeychainBuildTreeSettings.cmake")
|
||||
else()
|
||||
set(QTKEYCHAIN_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
|
||||
endif()
|
||||
|
||||
# Our library dependencies (contains definitions for IMPORTED targets)
|
||||
include("${QTKEYCHAIN_CMAKE_DIR}/Qt@QTKEYCHAIN_VERSION_INFIX@KeychainLibraryDepends.cmake")
|
||||
|
||||
# These are IMPORTED targets created by FooBarLibraryDepends.cmake
|
||||
set(QTKEYCHAIN_LIBRARIES "@QTKEYCHAIN_TARGET_NAME@")
|
||||
|
||||
set(QTKEYCHAIN_FOUND TRUE)
|
@ -1,11 +0,0 @@
|
||||
set(PACKAGE_VERSION "@QTKEYCHAIN_VERSION@")
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
@ -1,15 +0,0 @@
|
||||
QtKeychain
|
||||
==========
|
||||
|
||||
QtKeychain is a Qt API to store passwords and other secret data securely. How the data is stored depends on the platform:
|
||||
|
||||
* **Mac OS X:** Passwords are stored in the OS X Keychain.
|
||||
|
||||
* **Linux/Unix:** If running, GNOME Keyring is used, otherwise
|
||||
qtkeychain tries to use KWallet (via D-Bus), if available.
|
||||
|
||||
* **Windows:** Windows does not provide a service for secure storage. QtKeychain uses the Windows API function [CryptProtectData](http://msdn.microsoft.com/en-us/library/windows/desktop/aa380261%28v=vs.85%29.aspx "CryptProtectData function") to encrypt the password with the user's logon credentials. The encrypted data is then persisted via QSettings.
|
||||
|
||||
In unsupported environments QtKeychain will report an error. It will not store any data unencrypted unless explicitly requested (setInsecureFallback( true )).
|
||||
|
||||
**License:** QtKeychain is available under the [Modified BSD License](http://www.gnu.org/licenses/license-list.html#ModifiedBSD). See the file COPYING for details.
|
@ -1,15 +0,0 @@
|
||||
QtKeychain
|
||||
==========
|
||||
|
||||
QtKeychain is a Qt API to store passwords and other secret data securely. How the data is stored depends on the platform:
|
||||
|
||||
* **Mac OS X:** Passwords are stored in the OS X Keychain.
|
||||
|
||||
* **Linux/Unix:** If running, GNOME Keyring is used, otherwise
|
||||
qtkeychain tries to use KWallet (via D-Bus), if available.
|
||||
|
||||
* **Windows:** Windows does not provide a service for secure storage. QtKeychain uses the Windows API function [CryptProtectData](http://msdn.microsoft.com/en-us/library/windows/desktop/aa380261%28v=vs.85%29.aspx "CryptProtectData function") to encrypt the password with the user's logon credentials. The encrypted data is then persisted via QSettings.
|
||||
|
||||
In unsupported environments QtKeychain will report an error. It will not store any data unencrypted unless explicitly requested (setInsecureFallback( true )).
|
||||
|
||||
**License:** QtKeychain is available under the [Modified BSD License](http://www.gnu.org/licenses/license-list.html#ModifiedBSD). See the file COPYING for details.
|
@ -1,188 +0,0 @@
|
||||
# - Define GNU standard installation directories
|
||||
# Provides install directory variables as defined for GNU software:
|
||||
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
|
||||
# Inclusion of this module defines the following variables:
|
||||
# CMAKE_INSTALL_<dir> - destination for files of a given type
|
||||
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
|
||||
# where <dir> is one of:
|
||||
# BINDIR - user executables (bin)
|
||||
# SBINDIR - system admin executables (sbin)
|
||||
# LIBEXECDIR - program executables (libexec)
|
||||
# SYSCONFDIR - read-only single-machine data (etc)
|
||||
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
|
||||
# LOCALSTATEDIR - modifiable single-machine data (var)
|
||||
# LIBDIR - object code libraries (lib or lib64 or lib/<multiarch-tuple> on Debian)
|
||||
# INCLUDEDIR - C header files (include)
|
||||
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
|
||||
# DATAROOTDIR - read-only architecture-independent data root (share)
|
||||
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
|
||||
# INFODIR - info documentation (DATAROOTDIR/info)
|
||||
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
|
||||
# MANDIR - man documentation (DATAROOTDIR/man)
|
||||
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
|
||||
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
|
||||
# install() commands for the corresponding file type. If the includer does
|
||||
# not define a value the above-shown default will be used and the value will
|
||||
# appear in the cache for editing by the user.
|
||||
# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
|
||||
# from the corresponding destination by prepending (if necessary) the value
|
||||
# of CMAKE_INSTALL_PREFIX.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
|
||||
# Copyright 2011 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Installation directories
|
||||
#
|
||||
if(NOT DEFINED CMAKE_INSTALL_BINDIR)
|
||||
set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
|
||||
set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
|
||||
set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
|
||||
set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
|
||||
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||
set(_LIBDIR_DEFAULT "lib")
|
||||
# Override this default 'lib' with 'lib64' iff:
|
||||
# - we are on Linux system but NOT cross-compiling
|
||||
# - we are NOT on debian
|
||||
# - we are on a 64 bits system
|
||||
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
|
||||
# For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
|
||||
# CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
|
||||
# See http://wiki.debian.org/Multiarch
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux"
|
||||
AND NOT CMAKE_CROSSCOMPILING)
|
||||
if (EXISTS "/etc/debian_version") # is this a debian system ?
|
||||
if(CMAKE_LIBRARY_ARCHITECTURE)
|
||||
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
|
||||
endif()
|
||||
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
|
||||
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
|
||||
message(AUTHOR_WARNING
|
||||
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
|
||||
"Please enable at least one language before including GNUInstallDirs.")
|
||||
else()
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(_LIBDIR_DEFAULT "lib64")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
|
||||
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
|
||||
set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
|
||||
set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Values whose defaults are relative to DATAROOTDIR. Store empty values in
|
||||
# the cache and store the defaults in local variables if the cache values are
|
||||
# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
|
||||
|
||||
if(NOT CMAKE_INSTALL_DATADIR)
|
||||
set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
|
||||
set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_INFODIR)
|
||||
set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
|
||||
set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_LOCALEDIR)
|
||||
set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
|
||||
set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_MANDIR)
|
||||
set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
|
||||
set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_DOCDIR)
|
||||
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
|
||||
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
mark_as_advanced(
|
||||
CMAKE_INSTALL_BINDIR
|
||||
CMAKE_INSTALL_SBINDIR
|
||||
CMAKE_INSTALL_LIBEXECDIR
|
||||
CMAKE_INSTALL_SYSCONFDIR
|
||||
CMAKE_INSTALL_SHAREDSTATEDIR
|
||||
CMAKE_INSTALL_LOCALSTATEDIR
|
||||
CMAKE_INSTALL_LIBDIR
|
||||
CMAKE_INSTALL_INCLUDEDIR
|
||||
CMAKE_INSTALL_OLDINCLUDEDIR
|
||||
CMAKE_INSTALL_DATAROOTDIR
|
||||
CMAKE_INSTALL_DATADIR
|
||||
CMAKE_INSTALL_INFODIR
|
||||
CMAKE_INSTALL_LOCALEDIR
|
||||
CMAKE_INSTALL_MANDIR
|
||||
CMAKE_INSTALL_DOCDIR
|
||||
)
|
||||
|
||||
# Result directories
|
||||
#
|
||||
foreach(dir
|
||||
BINDIR
|
||||
SBINDIR
|
||||
LIBEXECDIR
|
||||
SYSCONFDIR
|
||||
SHAREDSTATEDIR
|
||||
LOCALSTATEDIR
|
||||
LIBDIR
|
||||
INCLUDEDIR
|
||||
OLDINCLUDEDIR
|
||||
DATAROOTDIR
|
||||
DATADIR
|
||||
INFODIR
|
||||
LOCALEDIR
|
||||
MANDIR
|
||||
DOCDIR
|
||||
)
|
||||
if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
|
||||
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
|
||||
endif()
|
||||
endforeach()
|
@ -1,71 +0,0 @@
|
||||
#include "gnomekeyring_p.h"
|
||||
|
||||
const char* GnomeKeyring::GNOME_KEYRING_DEFAULT = NULL;
|
||||
|
||||
bool GnomeKeyring::isAvailable()
|
||||
{
|
||||
const GnomeKeyring& keyring = instance();
|
||||
return keyring.isLoaded() &&
|
||||
keyring.NETWORK_PASSWORD &&
|
||||
keyring.is_available &&
|
||||
keyring.find_password &&
|
||||
keyring.store_password &&
|
||||
keyring.delete_password &&
|
||||
keyring.is_available();
|
||||
}
|
||||
|
||||
GnomeKeyring::gpointer GnomeKeyring::store_network_password( const gchar* keyring, const gchar* display_name,
|
||||
const gchar* user, const gchar* server, const gchar* password,
|
||||
OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data )
|
||||
{
|
||||
if ( !isAvailable() )
|
||||
return 0;
|
||||
return instance().store_password( instance().NETWORK_PASSWORD,
|
||||
keyring, display_name, password, callback, data, destroy_data,
|
||||
"user", user, "server", server, static_cast<char*>(0) );
|
||||
}
|
||||
|
||||
GnomeKeyring::gpointer GnomeKeyring::find_network_password( const gchar* user, const gchar* server,
|
||||
OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data )
|
||||
{
|
||||
if ( !isAvailable() )
|
||||
return 0;
|
||||
return instance().find_password( instance().NETWORK_PASSWORD,
|
||||
callback, data, destroy_data,
|
||||
"user", user, "server", server, static_cast<char*>(0) );
|
||||
}
|
||||
|
||||
GnomeKeyring::gpointer GnomeKeyring::delete_network_password( const gchar* user,
|
||||
const gchar* server,
|
||||
OperationDoneCallback callback,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy_data )
|
||||
{
|
||||
if ( !isAvailable() )
|
||||
return 0;
|
||||
return instance().delete_password( instance().NETWORK_PASSWORD,
|
||||
callback, data, destroy_data,
|
||||
"user", user, "server", server, static_cast<char*>(0) );
|
||||
}
|
||||
|
||||
GnomeKeyring::GnomeKeyring()
|
||||
: QLibrary("gnome-keyring", 0)
|
||||
{
|
||||
static const PasswordSchema schema = {
|
||||
ITEM_NETWORK_PASSWORD,
|
||||
{{ "user", ATTRIBUTE_TYPE_STRING },
|
||||
{ "server", ATTRIBUTE_TYPE_STRING },
|
||||
{ 0, static_cast<AttributeType>( 0 ) }}
|
||||
};
|
||||
|
||||
NETWORK_PASSWORD = &schema;
|
||||
is_available = reinterpret_cast<is_available_fn*>( resolve( "gnome_keyring_is_available" ) );
|
||||
find_password = reinterpret_cast<find_password_fn*>( resolve( "gnome_keyring_find_password" ) );
|
||||
store_password = reinterpret_cast<store_password_fn*>( resolve( "gnome_keyring_store_password" ) );
|
||||
delete_password = reinterpret_cast<delete_password_fn*>( resolve( "gnome_keyring_delete_password" ) );
|
||||
}
|
||||
|
||||
GnomeKeyring& GnomeKeyring::instance() {
|
||||
static GnomeKeyring keyring;
|
||||
return keyring;
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
#ifndef QTKEYCHAIN_GNOME_P_H
|
||||
#define QTKEYCHAIN_GNOME_P_H
|
||||
|
||||
#include <QLibrary>
|
||||
|
||||
class GnomeKeyring : private QLibrary {
|
||||
public:
|
||||
enum Result {
|
||||
RESULT_OK,
|
||||
RESULT_DENIED,
|
||||
RESULT_NO_KEYRING_DAEMON,
|
||||
RESULT_ALREADY_UNLOCKED,
|
||||
RESULT_NO_SUCH_KEYRING,
|
||||
RESULT_BAD_ARGUMENTS,
|
||||
RESULT_IO_ERROR,
|
||||
RESULT_CANCELLED,
|
||||
RESULT_KEYRING_ALREADY_EXISTS,
|
||||
RESULT_NO_MATCH
|
||||
};
|
||||
|
||||
enum ItemType {
|
||||
ITEM_GENERIC_SECRET = 0,
|
||||
ITEM_NETWORK_PASSWORD,
|
||||
ITEM_NOTE,
|
||||
ITEM_CHAINED_KEYRING_PASSWORD,
|
||||
ITEM_ENCRYPTION_KEY_PASSWORD,
|
||||
ITEM_PK_STORAGE = 0x100
|
||||
};
|
||||
|
||||
enum AttributeType {
|
||||
ATTRIBUTE_TYPE_STRING,
|
||||
ATTRIBUTE_TYPE_UINT32
|
||||
};
|
||||
|
||||
typedef char gchar;
|
||||
typedef void* gpointer;
|
||||
typedef bool gboolean;
|
||||
typedef struct {
|
||||
ItemType item_type;
|
||||
struct {
|
||||
const gchar* name;
|
||||
AttributeType type;
|
||||
} attributes[32];
|
||||
} PasswordSchema;
|
||||
|
||||
typedef void ( *OperationGetStringCallback )( Result result, const char* string, gpointer data );
|
||||
typedef void ( *OperationDoneCallback )( Result result, gpointer data );
|
||||
typedef void ( *GDestroyNotify )( gpointer data );
|
||||
|
||||
static const char* GNOME_KEYRING_DEFAULT;
|
||||
|
||||
static bool isAvailable();
|
||||
|
||||
static gpointer store_network_password( const gchar* keyring, const gchar* display_name,
|
||||
const gchar* user, const gchar* server, const gchar* password,
|
||||
OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data );
|
||||
|
||||
static gpointer find_network_password( const gchar* user, const gchar* server,
|
||||
OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data );
|
||||
|
||||
static gpointer delete_network_password( const gchar* user, const gchar* server,
|
||||
OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data );
|
||||
private:
|
||||
GnomeKeyring();
|
||||
|
||||
static GnomeKeyring& instance();
|
||||
|
||||
const PasswordSchema* NETWORK_PASSWORD;
|
||||
typedef gboolean ( is_available_fn )( void );
|
||||
typedef gpointer ( store_password_fn )( const PasswordSchema* schema, const gchar* keyring,
|
||||
const gchar* display_name, const gchar* password,
|
||||
OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data,
|
||||
... );
|
||||
typedef gpointer ( find_password_fn )( const PasswordSchema* schema,
|
||||
OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data,
|
||||
... );
|
||||
typedef gpointer ( delete_password_fn )( const PasswordSchema* schema,
|
||||
OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data,
|
||||
... );
|
||||
|
||||
is_available_fn* is_available;
|
||||
find_password_fn* find_password;
|
||||
store_password_fn* store_password;
|
||||
delete_password_fn* delete_password;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -1,229 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include "keychain.h"
|
||||
#include "keychain_p.h"
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
Job::Job( const QString& service, QObject *parent )
|
||||
: QObject( parent )
|
||||
, d ( new JobPrivate( service ) ) {
|
||||
}
|
||||
|
||||
Job::~Job() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString Job::service() const {
|
||||
return d->service;
|
||||
}
|
||||
|
||||
QSettings* Job::settings() const {
|
||||
return d->settings;
|
||||
}
|
||||
|
||||
void Job::setSettings( QSettings* settings ) {
|
||||
d->settings = settings;
|
||||
}
|
||||
|
||||
void Job::start() {
|
||||
QMetaObject::invokeMethod( this, "doStart", Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
bool Job::autoDelete() const {
|
||||
return d->autoDelete;
|
||||
}
|
||||
|
||||
void Job::setAutoDelete( bool autoDelete ) {
|
||||
d->autoDelete = autoDelete;
|
||||
}
|
||||
|
||||
bool Job::insecureFallback() const {
|
||||
return d->insecureFallback;
|
||||
}
|
||||
|
||||
void Job::setInsecureFallback( bool insecureFallback ) {
|
||||
d->insecureFallback = insecureFallback;
|
||||
}
|
||||
|
||||
void Job::emitFinished() {
|
||||
emit finished( this );
|
||||
if ( d->autoDelete )
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void Job::emitFinishedWithError( Error error, const QString& errorString ) {
|
||||
d->error = error;
|
||||
d->errorString = errorString;
|
||||
emitFinished();
|
||||
}
|
||||
|
||||
Error Job::error() const {
|
||||
return d->error;
|
||||
}
|
||||
|
||||
QString Job::errorString() const {
|
||||
return d->errorString;
|
||||
}
|
||||
|
||||
void Job::setError( Error error ) {
|
||||
d->error = error;
|
||||
}
|
||||
|
||||
void Job::setErrorString( const QString& errorString ) {
|
||||
d->errorString = errorString;
|
||||
}
|
||||
|
||||
ReadPasswordJob::ReadPasswordJob( const QString& service, QObject* parent )
|
||||
: Job( service, parent )
|
||||
, d( new ReadPasswordJobPrivate( this ) )
|
||||
{}
|
||||
|
||||
ReadPasswordJob::~ReadPasswordJob() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString ReadPasswordJob::textData() const {
|
||||
return QString::fromUtf8( d->data );
|
||||
}
|
||||
|
||||
QByteArray ReadPasswordJob::binaryData() const {
|
||||
return d->data;
|
||||
}
|
||||
|
||||
QString ReadPasswordJob::key() const {
|
||||
return d->key;
|
||||
}
|
||||
|
||||
void ReadPasswordJob::setKey( const QString& key ) {
|
||||
d->key = key;
|
||||
}
|
||||
|
||||
void ReadPasswordJob::doStart() {
|
||||
JobExecutor::instance()->enqueue( this );
|
||||
}
|
||||
|
||||
WritePasswordJob::WritePasswordJob( const QString& service, QObject* parent )
|
||||
: Job( service, parent )
|
||||
, d( new WritePasswordJobPrivate( this ) ) {
|
||||
}
|
||||
|
||||
WritePasswordJob::~WritePasswordJob() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString WritePasswordJob::key() const {
|
||||
return d->key;
|
||||
}
|
||||
|
||||
void WritePasswordJob::setKey( const QString& key ) {
|
||||
d->key = key;
|
||||
}
|
||||
|
||||
void WritePasswordJob::setBinaryData( const QByteArray& data ) {
|
||||
d->binaryData = data;
|
||||
d->mode = WritePasswordJobPrivate::Binary;
|
||||
}
|
||||
|
||||
void WritePasswordJob::setTextData( const QString& data ) {
|
||||
d->textData = data;
|
||||
d->mode = WritePasswordJobPrivate::Text;
|
||||
}
|
||||
|
||||
void WritePasswordJob::doStart() {
|
||||
JobExecutor::instance()->enqueue( this );
|
||||
}
|
||||
|
||||
DeletePasswordJob::DeletePasswordJob( const QString& service, QObject* parent )
|
||||
: Job( service, parent )
|
||||
, d( new DeletePasswordJobPrivate( this ) ) {
|
||||
}
|
||||
|
||||
DeletePasswordJob::~DeletePasswordJob() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
void DeletePasswordJob::doStart() {
|
||||
//Internally, to delete a password we just execute a write job with no data set (null byte array).
|
||||
//In all current implementations, this deletes the entry so this is sufficient
|
||||
WritePasswordJob* job = new WritePasswordJob( service(), this );
|
||||
connect( job, SIGNAL(finished(QKeychain::Job*)), d, SLOT(jobFinished(QKeychain::Job*)) );
|
||||
job->setInsecureFallback(true);
|
||||
job->setSettings(settings());
|
||||
job->setKey( d->key );
|
||||
job->doStart();
|
||||
}
|
||||
|
||||
QString DeletePasswordJob::key() const {
|
||||
return d->key;
|
||||
}
|
||||
|
||||
void DeletePasswordJob::setKey( const QString& key ) {
|
||||
d->key = key;
|
||||
}
|
||||
|
||||
void DeletePasswordJobPrivate::jobFinished( Job* job ) {
|
||||
q->setError( job->error() );
|
||||
q->setErrorString( job->errorString() );
|
||||
q->emitFinished();
|
||||
}
|
||||
|
||||
JobExecutor::JobExecutor()
|
||||
: QObject( 0 )
|
||||
, m_runningJob( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void JobExecutor::enqueue( Job* job ) {
|
||||
m_queue.append( job );
|
||||
startNextIfNoneRunning();
|
||||
}
|
||||
|
||||
void JobExecutor::startNextIfNoneRunning() {
|
||||
if ( m_queue.isEmpty() || m_runningJob )
|
||||
return;
|
||||
QPointer<Job> next;
|
||||
while ( !next && !m_queue.isEmpty() ) {
|
||||
next = m_queue.first();
|
||||
m_queue.pop_front();
|
||||
}
|
||||
if ( next ) {
|
||||
connect( next, SIGNAL(finished(QKeychain::Job*)), this, SLOT(jobFinished(QKeychain::Job*)) );
|
||||
connect( next, SIGNAL(destroyed(QObject*)), this, SLOT(jobDestroyed(QObject*)) );
|
||||
m_runningJob = next;
|
||||
if ( ReadPasswordJob* rpj = qobject_cast<ReadPasswordJob*>( m_runningJob ) )
|
||||
rpj->d->scheduledStart();
|
||||
else if ( WritePasswordJob* wpj = qobject_cast<WritePasswordJob*>( m_runningJob) )
|
||||
wpj->d->scheduledStart();
|
||||
}
|
||||
}
|
||||
|
||||
void JobExecutor::jobDestroyed( QObject* object ) {
|
||||
Q_UNUSED( object ) // for release mode
|
||||
Q_ASSERT( object == m_runningJob );
|
||||
m_runningJob->disconnect( this );
|
||||
m_runningJob = 0;
|
||||
startNextIfNoneRunning();
|
||||
}
|
||||
|
||||
void JobExecutor::jobFinished( Job* job ) {
|
||||
Q_UNUSED( job ) // for release mode
|
||||
Q_ASSERT( job == m_runningJob );
|
||||
m_runningJob->disconnect( this );
|
||||
m_runningJob = 0;
|
||||
startNextIfNoneRunning();
|
||||
}
|
||||
|
||||
JobExecutor* JobExecutor::s_instance = 0;
|
||||
|
||||
JobExecutor* JobExecutor::instance() {
|
||||
if ( !s_instance )
|
||||
s_instance = new JobExecutor;
|
||||
return s_instance;
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#ifndef KEYCHAIN_H
|
||||
#define KEYCHAIN_H
|
||||
|
||||
#include "qkeychain_export.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
|
||||
class QSettings;
|
||||
|
||||
#define QTKEYCHAIN_VERSION 0x000100
|
||||
|
||||
namespace QKeychain {
|
||||
|
||||
/**
|
||||
* Error codes
|
||||
*/
|
||||
enum Error {
|
||||
NoError=0, /**< No error occurred, operation was successful */
|
||||
EntryNotFound, /**< For the given key no data was found */
|
||||
CouldNotDeleteEntry, /**< Could not delete existing secret data */
|
||||
AccessDeniedByUser, /**< User denied access to keychain */
|
||||
AccessDenied, /**< Access denied for other reasons */
|
||||
NoBackendAvailable, /**< No platform-specific keychain service available */
|
||||
NotImplemented, /**< Not implemented on platform */
|
||||
OtherError /**< Something else went wrong (errorString() might provide details) */
|
||||
};
|
||||
|
||||
class JobExecutor;
|
||||
class JobPrivate;
|
||||
|
||||
class QKEYCHAIN_EXPORT Job : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Job( const QString& service, QObject* parent=0 );
|
||||
~Job();
|
||||
|
||||
QSettings* settings() const;
|
||||
void setSettings( QSettings* settings );
|
||||
|
||||
void start();
|
||||
|
||||
QString service() const;
|
||||
|
||||
Error error() const;
|
||||
QString errorString() const;
|
||||
|
||||
bool autoDelete() const;
|
||||
void setAutoDelete( bool autoDelete );
|
||||
|
||||
bool insecureFallback() const;
|
||||
void setInsecureFallback( bool insecureFallback );
|
||||
|
||||
Q_SIGNALS:
|
||||
void finished( QKeychain::Job* );
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE virtual void doStart() = 0;
|
||||
|
||||
void setError( Error error );
|
||||
void setErrorString( const QString& errorString );
|
||||
void emitFinished();
|
||||
void emitFinishedWithError(Error, const QString& errorString);
|
||||
|
||||
private:
|
||||
JobPrivate* const d;
|
||||
};
|
||||
|
||||
class ReadPasswordJobPrivate;
|
||||
|
||||
class QKEYCHAIN_EXPORT ReadPasswordJob : public Job {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ReadPasswordJob( const QString& service, QObject* parent=0 );
|
||||
~ReadPasswordJob();
|
||||
|
||||
QString key() const;
|
||||
void setKey( const QString& key );
|
||||
|
||||
QByteArray binaryData() const;
|
||||
QString textData() const;
|
||||
|
||||
protected:
|
||||
void doStart();
|
||||
|
||||
private:
|
||||
friend class QKeychain::ReadPasswordJobPrivate;
|
||||
friend class QKeychain::JobExecutor;
|
||||
ReadPasswordJobPrivate* const d;
|
||||
};
|
||||
|
||||
class WritePasswordJobPrivate;
|
||||
|
||||
class QKEYCHAIN_EXPORT WritePasswordJob : public Job {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WritePasswordJob( const QString& service, QObject* parent=0 );
|
||||
~WritePasswordJob();
|
||||
|
||||
QString key() const;
|
||||
void setKey( const QString& key );
|
||||
|
||||
void setBinaryData( const QByteArray& data );
|
||||
void setTextData( const QString& data );
|
||||
|
||||
protected:
|
||||
void doStart();
|
||||
|
||||
private:
|
||||
friend class QKeychain::JobExecutor;
|
||||
friend class QKeychain::WritePasswordJobPrivate;
|
||||
friend class DeletePasswordJob;
|
||||
WritePasswordJobPrivate* const d;
|
||||
};
|
||||
|
||||
class DeletePasswordJobPrivate;
|
||||
|
||||
class QKEYCHAIN_EXPORT DeletePasswordJob : public Job {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeletePasswordJob( const QString& service, QObject* parent=0 );
|
||||
~DeletePasswordJob();
|
||||
|
||||
QString key() const;
|
||||
void setKey( const QString& key );
|
||||
|
||||
protected:
|
||||
void doStart();
|
||||
|
||||
private:
|
||||
friend class QKeychain::DeletePasswordJobPrivate;
|
||||
DeletePasswordJobPrivate* const d;
|
||||
};
|
||||
|
||||
} // namespace QtKeychain
|
||||
|
||||
#endif
|
@ -1,161 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include "keychain_p.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Security/Security.h>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
template <typename T>
|
||||
struct Releaser {
|
||||
explicit Releaser( const T& v ) : value( v ) {}
|
||||
~Releaser() {
|
||||
CFRelease( value );
|
||||
}
|
||||
|
||||
const T value;
|
||||
};
|
||||
|
||||
static QString strForStatus( OSStatus os ) {
|
||||
const Releaser<CFStringRef> str( SecCopyErrorMessageString( os, 0 ) );
|
||||
const char * const buf = CFStringGetCStringPtr( str.value, kCFStringEncodingUTF8 );
|
||||
if ( !buf )
|
||||
return QObject::tr( "%1 (OSStatus %2)" )
|
||||
.arg( "OSX Keychain Error" ).arg( os );
|
||||
return QObject::tr( "%1 (OSStatus %2)" )
|
||||
.arg( QString::fromUtf8( buf, strlen( buf ) ) ).arg( os );
|
||||
}
|
||||
|
||||
static OSStatus readPw( QByteArray* pw,
|
||||
const QString& service,
|
||||
const QString& account,
|
||||
SecKeychainItemRef* ref ) {
|
||||
Q_ASSERT( pw );
|
||||
pw->clear();
|
||||
const QByteArray serviceData = service.toUtf8();
|
||||
const QByteArray accountData = account.toUtf8();
|
||||
|
||||
void* data = 0;
|
||||
UInt32 len = 0;
|
||||
|
||||
const OSStatus ret = SecKeychainFindGenericPassword( NULL, // default keychain
|
||||
serviceData.size(),
|
||||
serviceData.constData(),
|
||||
accountData.size(),
|
||||
accountData.constData(),
|
||||
&len,
|
||||
&data,
|
||||
ref );
|
||||
if ( ret == noErr ) {
|
||||
*pw = QByteArray( reinterpret_cast<const char*>( data ), len );
|
||||
const OSStatus ret2 = SecKeychainItemFreeContent ( 0, data );
|
||||
if ( ret2 != noErr )
|
||||
qWarning() << "Could not free item content: " << strForStatus( ret2 );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ReadPasswordJobPrivate::scheduledStart()
|
||||
{
|
||||
QString errorString;
|
||||
Error error = NoError;
|
||||
const OSStatus ret = readPw( &data, q->service(), q->key(), 0 );
|
||||
|
||||
switch ( ret ) {
|
||||
case noErr:
|
||||
break;
|
||||
case errSecItemNotFound:
|
||||
errorString = tr("Password not found");
|
||||
error = EntryNotFound;
|
||||
break;
|
||||
default:
|
||||
errorString = strForStatus( ret );
|
||||
error = OtherError;
|
||||
break;
|
||||
}
|
||||
q->emitFinishedWithError( error, errorString );
|
||||
}
|
||||
|
||||
|
||||
static QKeychain::Error deleteEntryImpl( const QString& service, const QString& account, QString* err ) {
|
||||
SecKeychainItemRef ref;
|
||||
QByteArray pw;
|
||||
const OSStatus ret1 = readPw( &pw, service, account, &ref );
|
||||
if ( ret1 == errSecItemNotFound )
|
||||
return NoError; // No item stored, we're done
|
||||
if ( ret1 != noErr ) {
|
||||
*err = strForStatus( ret1 );
|
||||
//TODO map error code, set errstr
|
||||
return OtherError;
|
||||
}
|
||||
const Releaser<SecKeychainItemRef> releaser( ref );
|
||||
|
||||
const OSStatus ret2 = SecKeychainItemDelete( ref );
|
||||
|
||||
if ( ret2 == noErr )
|
||||
return NoError;
|
||||
//TODO map error code
|
||||
*err = strForStatus( ret2 );
|
||||
return CouldNotDeleteEntry;
|
||||
}
|
||||
|
||||
static QKeychain::Error writeEntryImpl( const QString& service,
|
||||
const QString& account,
|
||||
const QByteArray& data,
|
||||
QString* err ) {
|
||||
Q_ASSERT( err );
|
||||
err->clear();
|
||||
const QByteArray serviceData = service.toUtf8();
|
||||
const QByteArray accountData = account.toUtf8();
|
||||
const OSStatus ret = SecKeychainAddGenericPassword( NULL, //default keychain
|
||||
serviceData.size(),
|
||||
serviceData.constData(),
|
||||
accountData.size(),
|
||||
accountData.constData(),
|
||||
data.size(),
|
||||
data.constData(),
|
||||
NULL //item reference
|
||||
);
|
||||
if ( ret != noErr ) {
|
||||
switch ( ret ) {
|
||||
case errSecDuplicateItem:
|
||||
{
|
||||
Error derr = deleteEntryImpl( service, account, err );
|
||||
if ( derr != NoError )
|
||||
return CouldNotDeleteEntry;
|
||||
else
|
||||
return writeEntryImpl( service, account, data, err );
|
||||
}
|
||||
default:
|
||||
*err = strForStatus( ret );
|
||||
return OtherError;
|
||||
}
|
||||
}
|
||||
|
||||
return NoError;
|
||||
}
|
||||
|
||||
void WritePasswordJobPrivate::scheduledStart()
|
||||
{
|
||||
QString errorString;
|
||||
Error error = NoError;
|
||||
|
||||
if ( mode == Delete ) {
|
||||
const Error derr = deleteEntryImpl( q->service(), key, &errorString );
|
||||
if ( derr != NoError )
|
||||
error = CouldNotDeleteEntry;
|
||||
q->emitFinishedWithError( error, errorString );
|
||||
return;
|
||||
}
|
||||
const QByteArray data = mode == Text ? textData.toUtf8() : binaryData;
|
||||
error = writeEntryImpl( q->service(), key, data, &errorString );
|
||||
q->emitFinishedWithError( error, errorString );
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#ifndef KEYCHAIN_P_H
|
||||
#define KEYCHAIN_P_H
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QSettings>
|
||||
#include <QVector>
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
|
||||
|
||||
#include <QDBusPendingCallWatcher>
|
||||
|
||||
#include "kwallet_interface.h"
|
||||
#else
|
||||
|
||||
class QDBusPendingCallWatcher;
|
||||
|
||||
#endif
|
||||
|
||||
#include "keychain.h"
|
||||
|
||||
namespace QKeychain {
|
||||
|
||||
class JobExecutor;
|
||||
|
||||
class JobPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
JobPrivate( const QString& service_ )
|
||||
: error( NoError )
|
||||
, service( service_ )
|
||||
, autoDelete( true )
|
||||
, insecureFallback( false ) {}
|
||||
|
||||
QKeychain::Error error;
|
||||
QString errorString;
|
||||
QString service;
|
||||
bool autoDelete;
|
||||
bool insecureFallback;
|
||||
QPointer<QSettings> settings;
|
||||
};
|
||||
|
||||
class ReadPasswordJobPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ReadPasswordJobPrivate( ReadPasswordJob* qq ) : q( qq ), walletHandle( 0 ), dataType( Text ) {}
|
||||
void scheduledStart();
|
||||
|
||||
ReadPasswordJob* const q;
|
||||
QByteArray data;
|
||||
QString key;
|
||||
int walletHandle;
|
||||
enum DataType {
|
||||
Binary,
|
||||
Text
|
||||
};
|
||||
DataType dataType;
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
|
||||
org::kde::KWallet* iface;
|
||||
static void gnomeKeyring_cb( int result, const char* string, ReadPasswordJobPrivate* data );
|
||||
friend class QKeychain::JobExecutor;
|
||||
void fallbackOnError(const QDBusError& err);
|
||||
|
||||
private Q_SLOTS:
|
||||
void kwalletWalletFound( QDBusPendingCallWatcher* watcher );
|
||||
void kwalletOpenFinished( QDBusPendingCallWatcher* watcher );
|
||||
void kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher );
|
||||
void kwalletReadFinished( QDBusPendingCallWatcher* watcher );
|
||||
#else //moc's too dumb to respect above macros, so just define empty slot implementations
|
||||
private Q_SLOTS:
|
||||
void kwalletWalletFound( QDBusPendingCallWatcher* ) {}
|
||||
void kwalletOpenFinished( QDBusPendingCallWatcher* ) {}
|
||||
void kwalletEntryTypeFinished( QDBusPendingCallWatcher* ) {}
|
||||
void kwalletReadFinished( QDBusPendingCallWatcher* ) {}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
class WritePasswordJobPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WritePasswordJobPrivate( WritePasswordJob* qq ) : q( qq ), mode( Delete ) {}
|
||||
void scheduledStart();
|
||||
|
||||
enum Mode {
|
||||
Delete,
|
||||
Text,
|
||||
Binary
|
||||
};
|
||||
|
||||
static QString modeToString(Mode m);
|
||||
static Mode stringToMode(const QString& s);
|
||||
|
||||
WritePasswordJob* const q;
|
||||
Mode mode;
|
||||
QString key;
|
||||
QByteArray binaryData;
|
||||
QString textData;
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
|
||||
org::kde::KWallet* iface;
|
||||
static void gnomeKeyring_cb( int result, WritePasswordJobPrivate* self );
|
||||
friend class QKeychain::JobExecutor;
|
||||
void fallbackOnError(const QDBusError& err);
|
||||
|
||||
private Q_SLOTS:
|
||||
void kwalletWalletFound( QDBusPendingCallWatcher* watcher );
|
||||
void kwalletOpenFinished( QDBusPendingCallWatcher* watcher );
|
||||
void kwalletWriteFinished( QDBusPendingCallWatcher* watcher );
|
||||
#else
|
||||
private Q_SLOTS:
|
||||
void kwalletWalletFound( QDBusPendingCallWatcher* ) {}
|
||||
void kwalletOpenFinished( QDBusPendingCallWatcher* ) {}
|
||||
void kwalletWriteFinished( QDBusPendingCallWatcher* ) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
class DeletePasswordJobPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeletePasswordJobPrivate( DeletePasswordJob* qq ) : q( qq ) {}
|
||||
void doStart();
|
||||
DeletePasswordJob* const q;
|
||||
QString key;
|
||||
private Q_SLOTS:
|
||||
void jobFinished( QKeychain::Job* );
|
||||
};
|
||||
|
||||
class JobExecutor : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
static JobExecutor* instance();
|
||||
|
||||
void enqueue( Job* job );
|
||||
|
||||
private:
|
||||
explicit JobExecutor();
|
||||
void startNextIfNoneRunning();
|
||||
|
||||
private Q_SLOTS:
|
||||
void jobFinished( QKeychain::Job* );
|
||||
void jobDestroyed( QObject* object );
|
||||
|
||||
private:
|
||||
static JobExecutor* s_instance;
|
||||
Job* m_runningJob;
|
||||
QVector<QPointer<Job> > m_queue;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // KEYCHAIN_P_H
|
@ -1,510 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include "keychain_p.h"
|
||||
#include "gnomekeyring_p.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <QScopedPointer>
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
static QString typeKey( const QString& key )
|
||||
{
|
||||
return QString::fromLatin1( "%1/type" ).arg( key );
|
||||
}
|
||||
|
||||
static QString dataKey( const QString& key )
|
||||
{
|
||||
return QString::fromLatin1( "%1/data" ).arg( key );
|
||||
}
|
||||
|
||||
enum KeyringBackend {
|
||||
Backend_GnomeKeyring,
|
||||
Backend_Kwallet4,
|
||||
Backend_Kwallet5
|
||||
};
|
||||
|
||||
enum DesktopEnvironment {
|
||||
DesktopEnv_Gnome,
|
||||
DesktopEnv_Kde4,
|
||||
DesktopEnv_Plasma5,
|
||||
DesktopEnv_Unity,
|
||||
DesktopEnv_Xfce,
|
||||
DesktopEnv_Other
|
||||
};
|
||||
|
||||
// the following detection algorithm is derived from chromium,
|
||||
// licensed under BSD, see base/nix/xdg_util.cc
|
||||
|
||||
static DesktopEnvironment getKdeVersion() {
|
||||
QString value = qgetenv("KDE_SESSION_VERSION");
|
||||
if ( value == "5" ) {
|
||||
return DesktopEnv_Plasma5;
|
||||
} else if (value == "4" ) {
|
||||
return DesktopEnv_Kde4;
|
||||
} else {
|
||||
// most likely KDE3
|
||||
return DesktopEnv_Other;
|
||||
}
|
||||
}
|
||||
|
||||
static DesktopEnvironment detectDesktopEnvironment() {
|
||||
QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP");
|
||||
if ( xdgCurrentDesktop == "GNOME" ) {
|
||||
return DesktopEnv_Gnome;
|
||||
} else if ( xdgCurrentDesktop == "Unity" ) {
|
||||
return DesktopEnv_Unity;
|
||||
} else if ( xdgCurrentDesktop == "KDE" ) {
|
||||
return getKdeVersion();
|
||||
}
|
||||
|
||||
QByteArray desktopSession = qgetenv("DESKTOP_SESSION");
|
||||
if ( desktopSession == "gnome" ) {
|
||||
return DesktopEnv_Gnome;
|
||||
} else if ( desktopSession == "kde" ) {
|
||||
return getKdeVersion();
|
||||
} else if ( desktopSession == "kde4" ) {
|
||||
return DesktopEnv_Kde4;
|
||||
} else if ( desktopSession.contains("xfce") || desktopSession == "xubuntu" ) {
|
||||
return DesktopEnv_Xfce;
|
||||
}
|
||||
|
||||
if ( !qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty() ) {
|
||||
return DesktopEnv_Gnome;
|
||||
} else if ( !qgetenv("KDE_FULL_SESSION").isEmpty() ) {
|
||||
return getKdeVersion();
|
||||
}
|
||||
|
||||
return DesktopEnv_Other;
|
||||
}
|
||||
|
||||
static KeyringBackend detectKeyringBackend()
|
||||
{
|
||||
switch (detectDesktopEnvironment()) {
|
||||
case DesktopEnv_Kde4:
|
||||
return Backend_Kwallet4;
|
||||
break;
|
||||
case DesktopEnv_Plasma5:
|
||||
return Backend_Kwallet5;
|
||||
break;
|
||||
// fall through
|
||||
case DesktopEnv_Gnome:
|
||||
case DesktopEnv_Unity:
|
||||
case DesktopEnv_Xfce:
|
||||
case DesktopEnv_Other:
|
||||
default:
|
||||
if ( GnomeKeyring::isAvailable() ) {
|
||||
return Backend_GnomeKeyring;
|
||||
} else {
|
||||
return Backend_Kwallet4;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static KeyringBackend getKeyringBackend()
|
||||
{
|
||||
static KeyringBackend backend = detectKeyringBackend();
|
||||
return backend;
|
||||
}
|
||||
|
||||
static void kwalletReadPasswordScheduledStartImpl(const char * service, const char * path, ReadPasswordJobPrivate * priv) {
|
||||
if ( QDBusConnection::sessionBus().isConnected() )
|
||||
{
|
||||
priv->iface = new org::kde::KWallet( QLatin1String(service), QLatin1String(path), QDBusConnection::sessionBus(), priv );
|
||||
const QDBusPendingReply<QString> reply = priv->iface->networkWallet();
|
||||
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, priv );
|
||||
priv->connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), priv, SLOT(kwalletWalletFound(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// D-Bus is not reachable so none can tell us something about KWalletd
|
||||
QDBusError err( QDBusError::NoServer, ReadPasswordJobPrivate::tr("D-Bus is not running") );
|
||||
priv->fallbackOnError( err );
|
||||
}
|
||||
}
|
||||
|
||||
void ReadPasswordJobPrivate::scheduledStart() {
|
||||
switch ( getKeyringBackend() ) {
|
||||
case Backend_GnomeKeyring:
|
||||
if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(), q->service().toUtf8().constData(),
|
||||
reinterpret_cast<GnomeKeyring::OperationGetStringCallback>( &ReadPasswordJobPrivate::gnomeKeyring_cb ),
|
||||
this, 0 ) )
|
||||
q->emitFinishedWithError( OtherError, tr("Unknown error") );
|
||||
break;
|
||||
|
||||
case Backend_Kwallet4:
|
||||
kwalletReadPasswordScheduledStartImpl("org.kde.kwalletd", "/modules/kwalletd", this);
|
||||
break;
|
||||
case Backend_Kwallet5:
|
||||
kwalletReadPasswordScheduledStartImpl("org.kde.kwalletd5", "/modules/kwalletd5", this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadPasswordJobPrivate::kwalletWalletFound(QDBusPendingCallWatcher *watcher)
|
||||
{
|
||||
watcher->deleteLater();
|
||||
const QDBusPendingReply<QString> reply = *watcher;
|
||||
const QDBusPendingReply<int> pendingReply = iface->open( reply.value(), 0, q->service() );
|
||||
QDBusPendingCallWatcher* pendingWatcher = new QDBusPendingCallWatcher( pendingReply, this );
|
||||
connect( pendingWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
static QPair<Error, QString> mapGnomeKeyringError( int result )
|
||||
{
|
||||
Q_ASSERT( result != GnomeKeyring::RESULT_OK );
|
||||
|
||||
switch ( result ) {
|
||||
case GnomeKeyring::RESULT_DENIED:
|
||||
return qMakePair( AccessDenied, QObject::tr("Access to keychain denied") );
|
||||
case GnomeKeyring::RESULT_NO_KEYRING_DAEMON:
|
||||
return qMakePair( NoBackendAvailable, QObject::tr("No keyring daemon") );
|
||||
case GnomeKeyring::RESULT_ALREADY_UNLOCKED:
|
||||
return qMakePair( OtherError, QObject::tr("Already unlocked") );
|
||||
case GnomeKeyring::RESULT_NO_SUCH_KEYRING:
|
||||
return qMakePair( OtherError, QObject::tr("No such keyring") );
|
||||
case GnomeKeyring::RESULT_BAD_ARGUMENTS:
|
||||
return qMakePair( OtherError, QObject::tr("Bad arguments") );
|
||||
case GnomeKeyring::RESULT_IO_ERROR:
|
||||
return qMakePair( OtherError, QObject::tr("I/O error") );
|
||||
case GnomeKeyring::RESULT_CANCELLED:
|
||||
return qMakePair( OtherError, QObject::tr("Cancelled") );
|
||||
case GnomeKeyring::RESULT_KEYRING_ALREADY_EXISTS:
|
||||
return qMakePair( OtherError, QObject::tr("Keyring already exists") );
|
||||
case GnomeKeyring::RESULT_NO_MATCH:
|
||||
return qMakePair( EntryNotFound, QObject::tr("No match") );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return qMakePair( OtherError, QObject::tr("Unknown error") );
|
||||
}
|
||||
|
||||
void ReadPasswordJobPrivate::gnomeKeyring_cb( int result, const char* string, ReadPasswordJobPrivate* self )
|
||||
{
|
||||
if ( result == GnomeKeyring::RESULT_OK ) {
|
||||
if ( self->dataType == ReadPasswordJobPrivate::Text )
|
||||
self->data = string;
|
||||
else
|
||||
self->data = QByteArray::fromBase64( string );
|
||||
self->q->emitFinished();
|
||||
} else {
|
||||
const QPair<Error, QString> errorResult = mapGnomeKeyringError( result );
|
||||
self->q->emitFinishedWithError( errorResult.first, errorResult.second );
|
||||
}
|
||||
}
|
||||
|
||||
void ReadPasswordJobPrivate::fallbackOnError(const QDBusError& err )
|
||||
{
|
||||
QScopedPointer<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.data();
|
||||
|
||||
if ( q->insecureFallback() && actual->contains( dataKey( key ) ) ) {
|
||||
|
||||
const WritePasswordJobPrivate::Mode mode = WritePasswordJobPrivate::stringToMode( actual->value( typeKey( key ) ).toString() );
|
||||
if (mode == WritePasswordJobPrivate::Binary)
|
||||
dataType = Binary;
|
||||
else
|
||||
dataType = Text;
|
||||
data = actual->value( dataKey( key ) ).toByteArray();
|
||||
|
||||
q->emitFinished();
|
||||
} else {
|
||||
if ( err.type() == QDBusError::ServiceUnknown ) //KWalletd not running
|
||||
q->emitFinishedWithError( NoBackendAvailable, tr("No keychain service available") );
|
||||
else
|
||||
q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
}
|
||||
}
|
||||
|
||||
void ReadPasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
const QDBusPendingReply<int> reply = *watcher;
|
||||
|
||||
QScopedPointer<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.data();
|
||||
|
||||
if ( reply.isError() ) {
|
||||
fallbackOnError( reply.error() );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( actual->contains( dataKey( key ) ) ) {
|
||||
// We previously stored data in the insecure QSettings, but now have KWallet available.
|
||||
// Do the migration
|
||||
|
||||
data = actual->value( dataKey( key ) ).toByteArray();
|
||||
const WritePasswordJobPrivate::Mode mode = WritePasswordJobPrivate::stringToMode( actual->value( typeKey( key ) ).toString() );
|
||||
actual->remove( key );
|
||||
|
||||
q->emitFinished();
|
||||
|
||||
|
||||
WritePasswordJob* j = new WritePasswordJob( q->service(), 0 );
|
||||
j->setSettings( q->settings() );
|
||||
j->setKey( key );
|
||||
j->setAutoDelete( true );
|
||||
if ( mode == WritePasswordJobPrivate::Binary )
|
||||
j->setBinaryData( data );
|
||||
else if ( mode == WritePasswordJobPrivate::Text )
|
||||
j->setTextData( QString::fromUtf8( data ) );
|
||||
else
|
||||
Q_ASSERT( false );
|
||||
|
||||
j->start();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
walletHandle = reply.value();
|
||||
|
||||
if ( walletHandle < 0 ) {
|
||||
q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") );
|
||||
return;
|
||||
}
|
||||
|
||||
const QDBusPendingReply<int> nextReply = iface->entryType( walletHandle, q->service(), key, q->service() );
|
||||
QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this );
|
||||
connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletEntryTypeFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
//Must be in sync with KWallet::EntryType (kwallet.h)
|
||||
enum KWalletEntryType {
|
||||
Unknown=0,
|
||||
Password,
|
||||
Stream,
|
||||
Map
|
||||
};
|
||||
|
||||
void ReadPasswordJobPrivate::kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
if ( watcher->isError() ) {
|
||||
const QDBusError err = watcher->error();
|
||||
q->emitFinishedWithError( OtherError, tr("Could not determine data type: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
const QDBusPendingReply<int> reply = *watcher;
|
||||
const int value = reply.value();
|
||||
|
||||
switch ( value ) {
|
||||
case Unknown:
|
||||
q->emitFinishedWithError( EntryNotFound, tr("Entry not found") );
|
||||
return;
|
||||
case Password:
|
||||
dataType = Text;
|
||||
break;
|
||||
case Stream:
|
||||
dataType = Binary;
|
||||
break;
|
||||
case Map:
|
||||
q->emitFinishedWithError( EntryNotFound, tr("Unsupported entry type 'Map'") );
|
||||
return;
|
||||
default:
|
||||
q->emitFinishedWithError( OtherError, tr("Unknown kwallet entry type '%1'").arg( value ) );
|
||||
return;
|
||||
}
|
||||
|
||||
const QDBusPendingCall nextReply = dataType == Text
|
||||
? QDBusPendingCall( iface->readPassword( walletHandle, q->service(), key, q->service() ) )
|
||||
: QDBusPendingCall( iface->readEntry( walletHandle, q->service(), key, q->service() ) );
|
||||
QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this );
|
||||
connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletReadFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
void ReadPasswordJobPrivate::kwalletReadFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
if ( watcher->isError() ) {
|
||||
const QDBusError err = watcher->error();
|
||||
q->emitFinishedWithError( OtherError, tr("Could not read password: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( dataType == Binary ) {
|
||||
QDBusPendingReply<QByteArray> reply = *watcher;
|
||||
data = reply.value();
|
||||
} else {
|
||||
QDBusPendingReply<QString> reply = *watcher;
|
||||
data = reply.value().toUtf8();
|
||||
}
|
||||
q->emitFinished();
|
||||
}
|
||||
|
||||
static void kwalletWritePasswordScheduledStart( const char * service, const char * path, WritePasswordJobPrivate * priv ) {
|
||||
if ( QDBusConnection::sessionBus().isConnected() )
|
||||
{
|
||||
priv->iface = new org::kde::KWallet( QLatin1String(service), QLatin1String(path), QDBusConnection::sessionBus(), priv );
|
||||
const QDBusPendingReply<QString> reply = priv->iface->networkWallet();
|
||||
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, priv );
|
||||
priv->connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), priv, SLOT(kwalletWalletFound(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// D-Bus is not reachable so none can tell us something about KWalletd
|
||||
QDBusError err( QDBusError::NoServer, WritePasswordJobPrivate::tr("D-Bus is not running") );
|
||||
priv->fallbackOnError( err );
|
||||
}
|
||||
}
|
||||
|
||||
void WritePasswordJobPrivate::scheduledStart() {
|
||||
switch ( getKeyringBackend() ) {
|
||||
case Backend_GnomeKeyring:
|
||||
if ( mode == WritePasswordJobPrivate::Delete ) {
|
||||
if ( !GnomeKeyring::delete_network_password( key.toUtf8().constData(), q->service().toUtf8().constData(),
|
||||
reinterpret_cast<GnomeKeyring::OperationDoneCallback>( &WritePasswordJobPrivate::gnomeKeyring_cb ),
|
||||
this, 0 ) )
|
||||
q->emitFinishedWithError( OtherError, tr("Unknown error") );
|
||||
} else {
|
||||
QByteArray password = mode == WritePasswordJobPrivate::Text ? textData.toUtf8() : binaryData.toBase64();
|
||||
QByteArray service = q->service().toUtf8();
|
||||
if ( !GnomeKeyring::store_network_password( GnomeKeyring::GNOME_KEYRING_DEFAULT, service.constData(),
|
||||
key.toUtf8().constData(), service.constData(), password.constData(),
|
||||
reinterpret_cast<GnomeKeyring::OperationDoneCallback>( &WritePasswordJobPrivate::gnomeKeyring_cb ),
|
||||
this, 0 ) )
|
||||
q->emitFinishedWithError( OtherError, tr("Unknown error") );
|
||||
}
|
||||
break;
|
||||
|
||||
case Backend_Kwallet4:
|
||||
kwalletWritePasswordScheduledStart("org.kde.kwalletd", "/modules/kwalletd", this);
|
||||
break;
|
||||
case Backend_Kwallet5:
|
||||
kwalletWritePasswordScheduledStart("org.kde.kwalletd5", "/modules/kwalletd5", this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QString WritePasswordJobPrivate::modeToString(Mode m)
|
||||
{
|
||||
switch (m) {
|
||||
case Delete:
|
||||
return QLatin1String("Delete");
|
||||
case Text:
|
||||
return QLatin1String("Text");
|
||||
case Binary:
|
||||
return QLatin1String("Binary");
|
||||
}
|
||||
|
||||
Q_ASSERT_X(false, Q_FUNC_INFO, "Unhandled Mode value");
|
||||
return QString();
|
||||
}
|
||||
|
||||
WritePasswordJobPrivate::Mode WritePasswordJobPrivate::stringToMode(const QString& s)
|
||||
{
|
||||
if (s == QLatin1String("Delete") || s == QLatin1String("0"))
|
||||
return Delete;
|
||||
if (s == QLatin1String("Text") || s == QLatin1String("1"))
|
||||
return Text;
|
||||
if (s == QLatin1String("Binary") || s == QLatin1String("2"))
|
||||
return Binary;
|
||||
|
||||
qCritical("Unexpected mode string '%s'", qPrintable(s));
|
||||
|
||||
return Text;
|
||||
}
|
||||
|
||||
void WritePasswordJobPrivate::fallbackOnError(const QDBusError &err)
|
||||
{
|
||||
QScopedPointer<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.data();
|
||||
|
||||
if ( !q->insecureFallback() ) {
|
||||
q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mode == Delete ) {
|
||||
actual->remove( key );
|
||||
actual->sync();
|
||||
|
||||
q->emitFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
actual->setValue( QString::fromLatin1( "%1/type" ).arg( key ), mode );
|
||||
if ( mode == Text )
|
||||
actual->setValue( QString::fromLatin1( "%1/data" ).arg( key ), textData.toUtf8() );
|
||||
else if ( mode == Binary )
|
||||
actual->setValue( QString::fromLatin1( "%1/data" ).arg( key ), binaryData );
|
||||
actual->sync();
|
||||
|
||||
q->emitFinished();
|
||||
}
|
||||
|
||||
void WritePasswordJobPrivate::gnomeKeyring_cb( int result, WritePasswordJobPrivate* self )
|
||||
{
|
||||
if ( result == GnomeKeyring::RESULT_OK ) {
|
||||
self->q->emitFinished();
|
||||
} else {
|
||||
const QPair<Error, QString> errorResult = mapGnomeKeyringError( result );
|
||||
self->q->emitFinishedWithError( errorResult.first, errorResult.second );
|
||||
}
|
||||
}
|
||||
|
||||
void WritePasswordJobPrivate::kwalletWalletFound(QDBusPendingCallWatcher *watcher)
|
||||
{
|
||||
watcher->deleteLater();
|
||||
const QDBusPendingReply<QString> reply = *watcher;
|
||||
const QDBusPendingReply<int> pendingReply = iface->open( reply.value(), 0, q->service() );
|
||||
QDBusPendingCallWatcher* pendingWatcher = new QDBusPendingCallWatcher( pendingReply, this );
|
||||
connect( pendingWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
void WritePasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
QDBusPendingReply<int> reply = *watcher;
|
||||
|
||||
QScopedPointer<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.data();
|
||||
|
||||
if ( reply.isError() ) {
|
||||
fallbackOnError( reply.error() );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( actual->contains( key ) )
|
||||
{
|
||||
// If we had previously written to QSettings, but we now have a kwallet available, migrate and delete old insecure data
|
||||
actual->remove( key );
|
||||
actual->sync();
|
||||
}
|
||||
|
||||
const int handle = reply.value();
|
||||
|
||||
if ( handle < 0 ) {
|
||||
q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") );
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusPendingReply<int> nextReply;
|
||||
|
||||
if ( !textData.isEmpty() )
|
||||
nextReply = iface->writePassword( handle, q->service(), key, textData, q->service() );
|
||||
else if ( !binaryData.isEmpty() )
|
||||
nextReply = iface->writeEntry( handle, q->service(), key, binaryData, q->service() );
|
||||
else
|
||||
nextReply = iface->removeEntry( handle, q->service(), key, q->service() );
|
||||
|
||||
QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this );
|
||||
connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletWriteFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
void WritePasswordJobPrivate::kwalletWriteFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
QDBusPendingReply<int> reply = *watcher;
|
||||
if ( reply.isError() ) {
|
||||
const QDBusError err = reply.error();
|
||||
q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
q->emitFinished();
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include "keychain_p.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
void ReadPasswordJobPrivate::scheduledStart() {
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
|
||||
QByteArray encrypted = actual->value( key ).toByteArray();
|
||||
if ( encrypted.isNull() ) {
|
||||
q->emitFinishedWithError( EntryNotFound, tr("Entry not found") );
|
||||
return;
|
||||
}
|
||||
|
||||
DATA_BLOB blob_in, blob_out;
|
||||
|
||||
blob_in.pbData = reinterpret_cast<BYTE*>( encrypted.data() );
|
||||
blob_in.cbData = encrypted.size();
|
||||
|
||||
const BOOL ret = CryptUnprotectData( &blob_in,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
&blob_out );
|
||||
if ( !ret ) {
|
||||
q->emitFinishedWithError( OtherError, tr("Could not decrypt data") );
|
||||
return;
|
||||
}
|
||||
|
||||
data = QByteArray( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
|
||||
SecureZeroMemory( blob_out.pbData, blob_out.cbData );
|
||||
LocalFree( blob_out.pbData );
|
||||
|
||||
q->emitFinished();
|
||||
}
|
||||
|
||||
void WritePasswordJobPrivate::scheduledStart() {
|
||||
if ( mode == Delete ) {
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
actual->remove( key );
|
||||
actual->sync();
|
||||
if ( actual->status() != QSettings::NoError ) {
|
||||
const QString err = actual->status() == QSettings::AccessError
|
||||
? tr("Could not delete encrypted data from settings: access error")
|
||||
: tr("Could not delete encrypted data from settings: format error");
|
||||
q->emitFinishedWithError( OtherError, err );
|
||||
} else {
|
||||
q->emitFinished();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = mode == Binary ? binaryData : textData.toUtf8();
|
||||
DATA_BLOB blob_in, blob_out;
|
||||
blob_in.pbData = reinterpret_cast<BYTE*>( data.data() );
|
||||
blob_in.cbData = data.size();
|
||||
const BOOL res = CryptProtectData( &blob_in,
|
||||
L"QKeychain-encrypted data",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
&blob_out );
|
||||
if ( !res ) {
|
||||
q->emitFinishedWithError( OtherError, tr("Encryption failed") ); //TODO more details available?
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray encrypted( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
|
||||
LocalFree( blob_out.pbData );
|
||||
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
actual->setValue( key, encrypted );
|
||||
actual->sync();
|
||||
if ( actual->status() != QSettings::NoError ) {
|
||||
|
||||
const QString errorString = actual->status() == QSettings::AccessError
|
||||
? tr("Could not store encrypted data in settings: access error")
|
||||
: tr("Could not store encrypted data in settings: format error");
|
||||
q->emitFinishedWithError( OtherError, errorString );
|
||||
return;
|
||||
}
|
||||
|
||||
q->emitFinished();
|
||||
}
|
@ -1,276 +0,0 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.kde.KWallet">
|
||||
<signal name="walletListDirty">
|
||||
</signal>
|
||||
<signal name="walletCreated">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletOpened">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletAsyncOpened">
|
||||
<arg name="tId" type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletDeleted">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletClosed">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletClosed">
|
||||
<arg name="handle" type="i" direction="out"/>
|
||||
</signal>
|
||||
<signal name="allWalletsClosed">
|
||||
</signal>
|
||||
<signal name="folderListUpdated">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="folderUpdated">
|
||||
<arg type="s" direction="out"/>
|
||||
<arg type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="applicationDisconnected">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
<arg name="application" type="s" direction="out"/>
|
||||
</signal>
|
||||
<method name="isEnabled">
|
||||
<arg type="b" direction="out"/>
|
||||
</method>
|
||||
<method name="open">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="openPath">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="path" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="openAsync">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
<arg name="handleSession" type="b" direction="in"/>
|
||||
</method>
|
||||
<method name="openPathAsync">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="path" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
<arg name="handleSession" type="b" direction="in"/>
|
||||
</method>
|
||||
<method name="close">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="force" type="b" direction="in"/>
|
||||
</method>
|
||||
<method name="close">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="force" type="b" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="sync">
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||
</method>
|
||||
<method name="deleteWallet">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="isOpen">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="isOpen">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="users">
|
||||
<arg type="as" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="changePassword">
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="wallets">
|
||||
<arg type="as" direction="out"/>
|
||||
</method>
|
||||
<method name="folderList">
|
||||
<arg type="as" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="hasFolder">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="createFolder">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="removeFolder">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="entryList">
|
||||
<arg type="as" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readEntry">
|
||||
<arg type="ay" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readMap">
|
||||
<arg type="ay" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readPassword">
|
||||
<arg type="s" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readEntryList">
|
||||
<arg type="a{sv}" direction="out"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readMapList">
|
||||
<arg type="a{sv}" direction="out"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readPasswordList">
|
||||
<arg type="a{sv}" direction="out"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="renameEntry">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="oldName" type="s" direction="in"/>
|
||||
<arg name="newName" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="writeEntry">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="value" type="ay" direction="in"/>
|
||||
<arg name="entryType" type="i" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="writeEntry">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="value" type="ay" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="writeMap">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="value" type="ay" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="writePassword">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="value" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="hasEntry">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="entryType">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="removeEntry">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="disconnectApplication">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="application" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="reconfigure">
|
||||
</method>
|
||||
<method name="folderDoesNotExist">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="keyDoesNotExist">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="closeAllWallets">
|
||||
</method>
|
||||
<method name="networkWallet">
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="localWallet">
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="pamOpen">
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="passwordHash" type="ay" direction="in"/>
|
||||
<arg name="sessionTimeout" type="i" direction="in"/>
|
||||
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
@ -1,17 +0,0 @@
|
||||
#ifndef QKEYCHAIN_EXPORT_H
|
||||
#define QKEYCHAIN_EXPORT_H
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
# ifdef QKEYCHAIN_STATICLIB
|
||||
# undef QKEYCHAIN_SHAREDLIB
|
||||
# define QKEYCHAIN_EXPORT
|
||||
# else
|
||||
# ifdef QKEYCHAIN_BUILD_QKEYCHAIN_LIB
|
||||
# define QKEYCHAIN_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QKEYCHAIN_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
@ -1,98 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include <QCoreApplication>
|
||||
#include <QStringList>
|
||||
|
||||
#include "keychain.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
static int printUsage() {
|
||||
std::cerr << "testclient store <account> <password>" << std::endl;
|
||||
std::cerr << "testclient restore <account>" << std::endl;
|
||||
std::cerr << "testclient delete <account>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main( int argc, char** argv ) {
|
||||
QCoreApplication app( argc, argv );
|
||||
const QStringList args = app.arguments();
|
||||
if ( args.count() < 2 )
|
||||
return printUsage();
|
||||
|
||||
QStringList::ConstIterator it = args.constBegin();
|
||||
++it;
|
||||
|
||||
if ( *it == QLatin1String("store") ) {
|
||||
if ( ++it == args.constEnd() )
|
||||
return printUsage();
|
||||
const QString acc = *it;
|
||||
if ( ++it == args.constEnd() )
|
||||
return printUsage();
|
||||
const QString pass = *it;
|
||||
if ( ++it != args.constEnd() )
|
||||
return printUsage();
|
||||
WritePasswordJob job( QLatin1String("qtkeychain-testclient") );
|
||||
job.setAutoDelete( false );
|
||||
job.setKey( acc );
|
||||
job.setTextData( pass );
|
||||
QEventLoop loop;
|
||||
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) );
|
||||
job.start();
|
||||
loop.exec();
|
||||
if ( job.error() ) {
|
||||
std::cerr << "Storing password failed: " << qPrintable(job.errorString()) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << "Password stored successfully" << std::endl;
|
||||
} else if ( *it == QLatin1String("restore") ) {
|
||||
if ( ++it == args.constEnd() )
|
||||
return printUsage();
|
||||
const QString acc = *it;
|
||||
if ( ++it != args.constEnd() )
|
||||
return printUsage();
|
||||
ReadPasswordJob job( QLatin1String("qtkeychain-testclient") );
|
||||
job.setAutoDelete( false );
|
||||
job.setKey( acc );
|
||||
QEventLoop loop;
|
||||
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) );
|
||||
job.start();
|
||||
loop.exec();
|
||||
|
||||
const QString pw = job.textData();
|
||||
if ( job.error() ) {
|
||||
std::cerr << "Restoring password failed: " << qPrintable(job.errorString()) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << qPrintable(pw) << std::endl;
|
||||
} else if ( *it == QLatin1String("delete") ) {
|
||||
if ( ++it == args.constEnd() )
|
||||
return printUsage();
|
||||
const QString acc = *it;
|
||||
if ( ++it != args.constEnd() )
|
||||
return printUsage();
|
||||
DeletePasswordJob job( QLatin1String("qtkeychain-testclient") );
|
||||
job.setAutoDelete( false );
|
||||
job.setKey( acc );
|
||||
QEventLoop loop;
|
||||
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) );
|
||||
job.start();
|
||||
loop.exec();
|
||||
|
||||
if ( job.error() ) {
|
||||
std::cerr << "Deleting password failed: " << qPrintable(job.errorString()) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << "Password deleted successfully" << std::endl;
|
||||
} else {
|
||||
return printUsage();
|
||||
}
|
||||
}
|
||||
|
@ -1,177 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="de_DE">
|
||||
<context>
|
||||
<name>QKeychain::ReadPasswordJobPrivate</name>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="140"/>
|
||||
<source>Unknown error</source>
|
||||
<translation>Unbekannter Fehler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="129"/>
|
||||
<source>D-Bus is not running</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="222"/>
|
||||
<source>No keychain service available</source>
|
||||
<translation>Kein Schlüsselbund-Dienst verfügbar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="224"/>
|
||||
<source>Could not open wallet: %1; %2</source>
|
||||
<translation>Konnte Brieftasche nicht öffnen: %1; %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="270"/>
|
||||
<source>Access to keychain denied</source>
|
||||
<translation>Zugriff auf Schlüsselbund verweigert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="291"/>
|
||||
<source>Could not determine data type: %1; %2</source>
|
||||
<translation>Datentyp kann nicht ermittelt werden: %1: %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="309"/>
|
||||
<source>Unsupported entry type 'Map'</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="312"/>
|
||||
<source>Unknown kwallet entry type '%1'</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="327"/>
|
||||
<source>Could not read password: %1; %2</source>
|
||||
<translation>Passwort konnte nicht ausgelesen werden: %1; %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_mac.cpp" line="76"/>
|
||||
<source>Password not found</source>
|
||||
<translation>Passwort nicht gefunden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="300"/>
|
||||
<location filename="../keychain_win.cpp" line="27"/>
|
||||
<source>Entry not found</source>
|
||||
<translation>Eintrag nicht gefunden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="44"/>
|
||||
<source>Could not decrypt data</source>
|
||||
<translation>Kann Daten nicht entschlüsseln</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QKeychain::WritePasswordJobPrivate</name>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="364"/>
|
||||
<location filename="../keychain_unix.cpp" line="372"/>
|
||||
<source>Unknown error</source>
|
||||
<translation>Unbekannter Fehler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="352"/>
|
||||
<source>D-Bus is not running</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="420"/>
|
||||
<location filename="../keychain_unix.cpp" line="505"/>
|
||||
<source>Could not open wallet: %1; %2</source>
|
||||
<translation>Konnte Brieftasche nicht öffnen: %1; %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="483"/>
|
||||
<source>Access to keychain denied</source>
|
||||
<translation>Zugriff auf Schlüsselbund verweigert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="64"/>
|
||||
<source>Could not delete encrypted data from settings: access error</source>
|
||||
<translation>Kann verschlüsselte Daten nicht aus den Einstellungen entfernen: Zugriffsfehler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="65"/>
|
||||
<source>Could not delete encrypted data from settings: format error</source>
|
||||
<translation>Kann verschlüsselte Daten nicht aus den Einstellungen entfernen: Formatfehler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="85"/>
|
||||
<source>Encryption failed</source>
|
||||
<translation>Verschlüsselung fehlgeschlagen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="100"/>
|
||||
<source>Could not store encrypted data in settings: access error</source>
|
||||
<translation>Kann verschlüsselte Daten nicht in den Einstellungen speichern: Zugriffsfehler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="101"/>
|
||||
<source>Could not store encrypted data in settings: format error</source>
|
||||
<translation>Kann verschlüsselte Daten nicht in den Einstellungen speichern: Formatfehler</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="167"/>
|
||||
<source>Access to keychain denied</source>
|
||||
<translation>Zugriff auf Schlüsselbund verweigert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="169"/>
|
||||
<source>No keyring daemon</source>
|
||||
<translation>Kein Schlüsselbund-Dienst </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="171"/>
|
||||
<source>Already unlocked</source>
|
||||
<translation>Bereits entsperrt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="173"/>
|
||||
<source>No such keyring</source>
|
||||
<translation>Kein solcher Schlüsselbund</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="175"/>
|
||||
<source>Bad arguments</source>
|
||||
<translation>Ungültige Argumente</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="177"/>
|
||||
<source>I/O error</source>
|
||||
<translation>Ein-/Ausgabe-Fehler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="179"/>
|
||||
<source>Cancelled</source>
|
||||
<translation>Abgebrochen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="181"/>
|
||||
<source>Keyring already exists</source>
|
||||
<translation>Schlüsselbund existiert bereits</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="183"/>
|
||||
<source>No match</source>
|
||||
<translation>Kein Treffer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="188"/>
|
||||
<source>Unknown error</source>
|
||||
<translation>Unbekannter Fehler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_mac.cpp" line="31"/>
|
||||
<location filename="../keychain_mac.cpp" line="33"/>
|
||||
<source>%1 (OSStatus %2)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
@ -1,178 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ro_RO">
|
||||
<context>
|
||||
<name>QKeychain::ReadPasswordJobPrivate</name>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="140"/>
|
||||
<source>Unknown error</source>
|
||||
<translation>Eroare necunoscută</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="129"/>
|
||||
<source>D-Bus is not running</source>
|
||||
<translation>D-Bus nu rulează</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="222"/>
|
||||
<source>No keychain service available</source>
|
||||
<translatorcomment>Nu există niciun serviciu de chei disponibil</translatorcomment>
|
||||
<translation>Kein Schlüsselbund-Dienst verfügbar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="224"/>
|
||||
<source>Could not open wallet: %1; %2</source>
|
||||
<translation>Nu se poate deschide portofelul: %1; %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="270"/>
|
||||
<source>Access to keychain denied</source>
|
||||
<translation>Acces interzis la serviciul de chei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="291"/>
|
||||
<source>Could not determine data type: %1; %2</source>
|
||||
<translation>Nu se poate stabili tipul de date: %1: %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="309"/>
|
||||
<source>Unsupported entry type 'Map'</source>
|
||||
<translation>Tip de înregistrare nesuportat 'Map'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="312"/>
|
||||
<source>Unknown kwallet entry type '%1'</source>
|
||||
<translation>Tip de înregistrare kwallet necunoscut '%1'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="327"/>
|
||||
<source>Could not read password: %1; %2</source>
|
||||
<translation>Nu se poate citi parola: %1; %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_mac.cpp" line="76"/>
|
||||
<source>Password not found</source>
|
||||
<translation>Parola nu a fost găsită</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="300"/>
|
||||
<location filename="../keychain_win.cpp" line="27"/>
|
||||
<source>Entry not found</source>
|
||||
<translation>Înregistrarea nu a fost găsită</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="44"/>
|
||||
<source>Could not decrypt data</source>
|
||||
<translation>Nu se poate decripta data</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QKeychain::WritePasswordJobPrivate</name>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="364"/>
|
||||
<location filename="../keychain_unix.cpp" line="372"/>
|
||||
<source>Unknown error</source>
|
||||
<translation>Eroare necunoscută</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="352"/>
|
||||
<source>D-Bus is not running</source>
|
||||
<translation>D-Bus nu rulează</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="420"/>
|
||||
<location filename="../keychain_unix.cpp" line="505"/>
|
||||
<source>Could not open wallet: %1; %2</source>
|
||||
<translation>Nu se poate deschide portofelul: %1; %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="483"/>
|
||||
<source>Access to keychain denied</source>
|
||||
<translation>Acces interzis la serviciul de chei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="64"/>
|
||||
<source>Could not delete encrypted data from settings: access error</source>
|
||||
<translation>Nu se pot șterge datele criptate din setări: eroare de acces</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="65"/>
|
||||
<source>Could not delete encrypted data from settings: format error</source>
|
||||
<translation>Nu se pot șterge datele criptate din setări: eroare de format</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="85"/>
|
||||
<source>Encryption failed</source>
|
||||
<translation>Criptarea a eșuat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="100"/>
|
||||
<source>Could not store encrypted data in settings: access error</source>
|
||||
<translation>Nu se pot stoca datele criptate în setări: eroare de acces</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_win.cpp" line="101"/>
|
||||
<source>Could not store encrypted data in settings: format error</source>
|
||||
<translation>Nu se pot stoca datele criptate în setări: eroare de format</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="167"/>
|
||||
<source>Access to keychain denied</source>
|
||||
<translation>Acces interzis la serviciul de chei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="169"/>
|
||||
<source>No keyring daemon</source>
|
||||
<translation>Niciun demon pentru inelul de chei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="171"/>
|
||||
<source>Already unlocked</source>
|
||||
<translation>Deja deblocat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="173"/>
|
||||
<source>No such keyring</source>
|
||||
<translation>Nu există astfel de inel de chei</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="175"/>
|
||||
<source>Bad arguments</source>
|
||||
<translation>Argumente greșite</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="177"/>
|
||||
<source>I/O error</source>
|
||||
<translation>Eroare de I/E</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="179"/>
|
||||
<source>Cancelled</source>
|
||||
<translation>Anulat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="181"/>
|
||||
<source>Keyring already exists</source>
|
||||
<translation>Inelul de chei deja există</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="183"/>
|
||||
<source>No match</source>
|
||||
<translation>Nicio potrivire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_unix.cpp" line="188"/>
|
||||
<source>Unknown error</source>
|
||||
<translation>Eroare necunoscută</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../keychain_mac.cpp" line="31"/>
|
||||
<location filename="../keychain_mac.cpp" line="33"/>
|
||||
<source>%1 (OSStatus %2)</source>
|
||||
<translation>%1 (OSStatus %2)</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
65
fuel.pro
65
fuel.pro
@ -2,11 +2,10 @@
|
||||
# Fuel
|
||||
#-------------------------------------------------
|
||||
|
||||
QT = core gui webkit
|
||||
QT += core gui webkit
|
||||
|
||||
contains(QT_VERSION, ^5\\..*) {
|
||||
QT += widgets webkitwidgets
|
||||
QT -= quick multimediawidgets opengl printsupport qml multimedia positioning sensors
|
||||
}
|
||||
|
||||
TARGET = Fuel
|
||||
@ -53,86 +52,34 @@ SOURCES += src/main.cpp\
|
||||
src/CommitDialog.cpp \
|
||||
src/FileActionDialog.cpp \
|
||||
src/SettingsDialog.cpp \
|
||||
src/FslSettingsDialog.cpp \
|
||||
src/CloneDialog.cpp \
|
||||
src/RevisionDialog.cpp \
|
||||
src/Utils.cpp \
|
||||
src/FileTableView.cpp \
|
||||
src/CloneDialog.cpp \
|
||||
src/LoggedProcess.cpp \
|
||||
src/BrowserWidget.cpp \
|
||||
src/CustomWebView.cpp \
|
||||
src/Fossil.cpp \
|
||||
src/Workspace.cpp \
|
||||
src/SearchBox.cpp \
|
||||
src/Settings.cpp \
|
||||
src/RemoteDialog.cpp \
|
||||
src/AboutDialog.cpp
|
||||
src/CustomWebView.cpp
|
||||
|
||||
HEADERS += src/MainWindow.h \
|
||||
src/CommitDialog.h \
|
||||
src/FileActionDialog.h \
|
||||
src/SettingsDialog.h \
|
||||
src/FslSettingsDialog.h \
|
||||
src/CloneDialog.h \
|
||||
src/RevisionDialog.h \
|
||||
src/Utils.h \
|
||||
src/FileTableView.h \
|
||||
src/CloneDialog.h \
|
||||
src/LoggedProcess.h \
|
||||
src/BrowserWidget.h \
|
||||
src/CustomWebView.h \
|
||||
src/Fossil.h \
|
||||
src/Workspace.h \
|
||||
src/SearchBox.h \
|
||||
src/Settings.h \
|
||||
src/RemoteDialog.h \
|
||||
src/AboutDialog.h
|
||||
src/CustomWebView.h
|
||||
|
||||
FORMS += ui/MainWindow.ui \
|
||||
ui/CommitDialog.ui \
|
||||
ui/FileActionDialog.ui \
|
||||
ui/SettingsDialog.ui \
|
||||
ui/FslSettingsDialog.ui \
|
||||
ui/CloneDialog.ui \
|
||||
ui/BrowserWidget.ui \
|
||||
ui/RevisionDialog.ui \
|
||||
ui/RemoteDialog.ui \
|
||||
ui/AboutDialog.ui
|
||||
ui/BrowserWidget.ui
|
||||
|
||||
RESOURCES += \
|
||||
rsrc/resources.qrc
|
||||
|
||||
# QtKeychain
|
||||
SOURCES += ext/qtkeychain/keychain.cpp
|
||||
|
||||
HEADERS += ext/qtkeychain/keychain.h \
|
||||
ext/qtkeychain/keychain_p.h \
|
||||
ext/qtkeychain/qkeychain_export.h
|
||||
|
||||
DEFINES += QKEYCHAIN_STATICLIB
|
||||
|
||||
unix:!macx {
|
||||
QT += dbus
|
||||
|
||||
SOURCES += ext/qtkeychain/keychain_unix.cpp \
|
||||
ext/qtkeychain/gnomekeyring.cpp
|
||||
|
||||
HEADERS += ext/qtkeychain/gnomekeyring_p.h
|
||||
DBUS_INTERFACES += ext/qtkeychain/org.kde.KWallet.xml
|
||||
}
|
||||
|
||||
macx {
|
||||
SOURCES += ext/qtkeychain/keychain_mac.cpp
|
||||
LIBS += -framework CoreFoundation -framework Security
|
||||
}
|
||||
|
||||
win32 {
|
||||
SOURCES += ext/qtkeychain/keychain_win.cpp
|
||||
LIBS += -lCrypt32
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
CODECFORTR = UTF-8
|
||||
|
||||
TRANSLATIONS += \
|
||||
|
@ -1,14 +1,12 @@
|
||||
#!/bin/sh
|
||||
SCRIPTDIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
#!/bin/bash
|
||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
PRJDIR=$SCRIPTDIR/..
|
||||
INTLDIR=$SCRIPTDIR
|
||||
|
||||
# Detect lrelease tool
|
||||
if which lrelease-qt5 2>/dev/null; then
|
||||
if hash lrelease-qt5 2>/dev/null; then
|
||||
LRELEASE="lrelease-qt5"
|
||||
elif which lrelease4 2>/dev/null; then
|
||||
LRELEASE="lrelease4"
|
||||
elif which lrelease 2>/dev/null; then
|
||||
elif hash lrelease 2>/dev/null; then
|
||||
LRELEASE="lrelease"
|
||||
else
|
||||
echo "lrelease not found"
|
||||
|
94
manifest
94
manifest
@ -1,5 +1,5 @@
|
||||
C Updated\sChanges.md
|
||||
D 2015-08-25T13:07:48.374
|
||||
C Updated\sthe\sChanges.md
|
||||
D 2015-08-23T14:11:16.693
|
||||
F .travis.yml 77966888a81c4ceee1fcc79bce842c9667ad8a35
|
||||
F debian/changelog eb4304dfcb6bb66850ec740838090eb50ce1249b
|
||||
F debian/compat b6abd567fa79cbe0196d093a067271361dc6ca8b
|
||||
@ -10,36 +10,14 @@ F debian/menu aa1321fe6597a631df5cc978a3cf7b21ac1a3657
|
||||
F debian/rules 468914cbcf1bcc252ab3f616e1fdc2b37bc10b5d x
|
||||
F debian/source/format 1064dc0ce263680c076a1005f35ec906a5cf5a32
|
||||
F debian/watch 34f0921ff100a3e16a7ad84dcc303731de830a60
|
||||
F dist/arch/PKGBUILD 26623327e467028a883cd13963daa36baf10dfa3
|
||||
F dist/arch/PKGBUILD c9d706805891dadfab933c703e19dc86f084d328
|
||||
F dist/win/fuel.iss ef3558dbba409eb194938b930377fc9ee27d319e
|
||||
F doc/Building.md 149d959751ae488829e084a9f88449a08220c1d1
|
||||
F doc/Changes.md 47e0d70b5b4ce6e11688a807952d72134d4ff643
|
||||
F doc/Changes.md 9546f046a1c37ea6011cdae77da24df883a8e0ee
|
||||
F doc/License.txt 4cc77b90af91e615a64ae04893fdffa7939db84c
|
||||
F ext/qtkeychain/CMakeLists.txt fc1afa05034f2765ba243ce758a7e9d6b6efe2d6
|
||||
F ext/qtkeychain/COPYING d0f83c8198fdd5464d2373015b7b64ce7cae607e
|
||||
F ext/qtkeychain/ChangeLog 1703279e17036995806ba1719033d14840a8a7e2
|
||||
F ext/qtkeychain/QtKeychainBuildTreeSettings.cmake.in a50c3b646181124f15b946c3297f13012e959341
|
||||
F ext/qtkeychain/QtKeychainConfig.cmake.in ac7c87e54854a06c51e00f833f21f8323d1e6884
|
||||
F ext/qtkeychain/QtKeychainConfigVersion.cmake.in 3b650037d5775f28802c0471afe2cf6dbe51084e
|
||||
F ext/qtkeychain/ReadMe.markdown 65fe7f400600aa98a9a7fa5c3fc842ad8699cc43
|
||||
F ext/qtkeychain/ReadMe.txt 65fe7f400600aa98a9a7fa5c3fc842ad8699cc43
|
||||
F ext/qtkeychain/cmake/Modules/GNUInstallDirs.cmake 7a2ccf81f25546e93a6f48c792cdebaae51857e9
|
||||
F ext/qtkeychain/gnomekeyring.cpp 7fa97bd4ffb7c9df00d25e56cd9173d34109afe6
|
||||
F ext/qtkeychain/gnomekeyring_p.h 7f6acaf6d00b36bd08f5f31ba9136efa969e9875
|
||||
F ext/qtkeychain/keychain.cpp 427cbda7c6a76de995b1f1b4caa700cd06a9d19a
|
||||
F ext/qtkeychain/keychain.h f084c671b481af6ac7ce00bf641055a3cfc9cf9b
|
||||
F ext/qtkeychain/keychain_mac.cpp a028f6fc5e40f9ab88c94ebe30b8b0ae417f2f34
|
||||
F ext/qtkeychain/keychain_p.h 36f4caee2cbdbde971a1105ab388681ad2924665
|
||||
F ext/qtkeychain/keychain_unix.cpp 8e657da9acd9e86b2fdec19dc40f1afa4a1c5191
|
||||
F ext/qtkeychain/keychain_win.cpp e52877828703650219c1c674e618c7211f588d0d
|
||||
F ext/qtkeychain/org.kde.KWallet.xml f3729fda9f8fa8031a6f69415dcc29455c3c9ae6
|
||||
F ext/qtkeychain/qkeychain_export.h d756528188ef9bf3c4461ecc80048f06c362b54b
|
||||
F ext/qtkeychain/testclient.cpp cb1290a9584b627306a7bfdf1c02a8bbae503f5f
|
||||
F ext/qtkeychain/translations/qtkeychain_de.ts 0a70c8205c066c30ed8172f0670942de1fc5eede
|
||||
F ext/qtkeychain/translations/qtkeychain_ro.ts f16939382fd1a047b0692426bc82847347f14b32
|
||||
F fuel.pro 2de14a4a6bd3e5af9d9e7c78f870453fedb38577
|
||||
F fuel.pro d2d1fd2b3a9169a95e25235e07c7fa8f098a8c40
|
||||
F intl/convert.bat 357d461ee8c6a7be6d2f60ac77c3232678ffb513 x
|
||||
F intl/convert.sh ac6edc8d99b575601cf9c6b85b18c9e25875b6e0 x
|
||||
F intl/convert.sh 2ca2179ff53e727f241925b75e19182607883c45 x
|
||||
F intl/de_DE.ts e2faceab920ac60c97bbc6fba038e261d51fc741
|
||||
F intl/el_GR.ts 1b805ee57309d02059d9e3e4cb49d945f9d9ac82
|
||||
F intl/en_US.ts 7917816efedf35d5f4f798d18896d7aa0cb3c71b
|
||||
@ -51,8 +29,6 @@ F intl/nl_NL.ts ff9b6ae9da5b6ffacc74fc1075a14ad80ebc0429
|
||||
F intl/pt_PT.ts f93bcc3df5447ab1d85407e1dec4cd68c03d2245
|
||||
F intl/ru_RU.ts 74189b3ee2b30b0b47b2db5bd7c9935db84947fc
|
||||
F intl/update.sh 39d4561630ba6681bb27e7beadc225a31469728f x
|
||||
F rsrc/docs/Licenses.txt 4021c1b126d55c1630ae2b43a8b805f99e39a357
|
||||
F rsrc/docs/Translators.txt caf04efd7391546adda7da73679156e3ff5d5fcd
|
||||
F rsrc/fuel.desktop 43145556bc61f5a91b497c38a16aec44af271d29
|
||||
F rsrc/fuel.rc 8e9ac966f283102c11a77cd7f936cdc09e09bd79
|
||||
F rsrc/icons/Address\sBook-01.png ef2cec80ea5a559b72e8be4a344a1869fe69cbd8
|
||||
@ -210,57 +186,37 @@ F rsrc/icons/Zoom-01.png 67ca532922e9166325c5c75fce1ca3fbb0d2b6a6
|
||||
F rsrc/icons/fuel.icns 81e535004b62db801a02f3e15d0a33afc9d4070b
|
||||
F rsrc/icons/fuel.ico eb529ab3332a17b9302ef3e851db5b9ebce2a038
|
||||
F rsrc/icons/fuel.png 40daf53b7f6bdcdd0d6aa5ef433d078ec5ea4342
|
||||
F rsrc/resources.qrc 21ae6205e27ac989001eb0edc075d7e405b992c8
|
||||
F src/AboutDialog.cpp fc9e3ba03aa6cb145ace610d9b38a2de157551ba
|
||||
F src/AboutDialog.h 269f3a0589067c08f19b542e4576b0ef58bc6ec5
|
||||
F rsrc/resources.qrc 3dee01bfbf8b9ec67a04b9259f4fd358f33356b7
|
||||
F src/BrowserWidget.cpp 8b8f545cdff4a4188edc698a1b4777f5df46f056
|
||||
F src/BrowserWidget.h 764d66aa9a93b890298bd0301097739cb4e16597
|
||||
F src/CloneDialog.cpp c341622b01d493387d6e4928018b3392d92471e8
|
||||
F src/CloneDialog.h 8813d91f893eb3eb86a4ea5e50f9a53a0ea07047
|
||||
F src/CommitDialog.cpp 3d25ae2aa8af0ab417736a3f2d7f95a8dcb7480a
|
||||
F src/CommitDialog.h 921bf27c0c538ab9e9d6bdc750064337d346270b
|
||||
F src/CloneDialog.cpp 812ef7d361c16da21540b7047c9d4d5e74f18539
|
||||
F src/CloneDialog.h e9f0fc8e5cc5ea2e7c43d6e77b5c4a9cc850b59e
|
||||
F src/CommitDialog.cpp 5300522ac11bc1096a11a6ce22f8c1665d4afc05
|
||||
F src/CommitDialog.h f1ee8db92103164e7db55a8407ccdcff24571b72
|
||||
F src/CustomWebView.cpp b7dd0c41977c2cba005df07ed8967ba6f58d07d9
|
||||
F src/CustomWebView.h fbc8ee55812d1acb3c3b2bc31be7533e8a112822
|
||||
F src/FileActionDialog.cpp fcaebf9986f789b3440d5390b3458ad5f86fe0c8
|
||||
F src/FileActionDialog.h 15db1650b3a13d70bc338371e4c033c66e3b79ce
|
||||
F src/FileTableView.cpp 5ddf8c391c9a3ac449ec61fb1db837b577afeec2
|
||||
F src/FileTableView.h 03e56d87c2d46411b9762b87f4d301619aaf18df
|
||||
F src/Fossil.cpp e3451ddd8f19f1b6f2d446d9390b336e493da197
|
||||
F src/Fossil.h 7acbd4a9d43f6a11c183dbffd73b71d54a4c5108
|
||||
F src/FslSettingsDialog.cpp e00907d493fba469e48a008aecda88426350b5ac
|
||||
F src/FslSettingsDialog.h dfe2a61884a55a74cbb9206b6f6b482b979725e7
|
||||
F src/LoggedProcess.cpp 2a1e5c94bc1e57c8984563e66c210e43a14dc60c
|
||||
F src/LoggedProcess.h 85df7c635c807a5a0e8c4763f17a0752aaff7261
|
||||
F src/MainWindow.cpp 47aa96182c3a005d27295ef52e351f57a79721da
|
||||
F src/MainWindow.h f4cffbe4d360d30aa2eeaa25fc6d50d0a39c617f
|
||||
F src/RemoteDialog.cpp 8540cc5e2e41c4127ed8a028d84691604fa6ecac
|
||||
F src/RemoteDialog.h 5e0438c2bd7c79b1bb44bfbd58c2181b544a9e5d
|
||||
F src/RevisionDialog.cpp e58c4f8a704f00addebb15d521b76620fdafda79
|
||||
F src/RevisionDialog.h b718c3009342eaabad39c8a11a253a4e4fef7a73
|
||||
F src/SearchBox.cpp d4209c575baa9933e1ce5ed376e785b289a145ba
|
||||
F src/SearchBox.h 0c78d3a68136dab3e0e71b83ae36f22bd2688ab2
|
||||
F src/Settings.cpp 258d3f466f6a125ce2b8519d6d57a312cbc44a3f
|
||||
F src/Settings.h 0a10b0b83fe804bdc7dac58eed06b5b6ee422055
|
||||
F src/SettingsDialog.cpp fa0c70eaf0fa7edb15de302d041cdb552fe523d5
|
||||
F src/SettingsDialog.h 5eb3ae2cbb00ab5544e1889860f5376f69fe47cd
|
||||
F src/Utils.cpp fb9fe1caeef47dca310079f8f10b41c838defaa5
|
||||
F src/Utils.h 4563194b65d0a903ba71b3fec8fc870a8a610f76
|
||||
F src/Workspace.cpp 6f15ea480579f357a3e01dacd1d62c2621961478
|
||||
F src/Workspace.h 50970993b6f49c0f4dc55ba5954e7e4c2a723539
|
||||
F src/main.cpp d8c65ea5e54102e4989fef9fd8cfd4f13ef8a8f0
|
||||
F src/MainWindow.cpp 96c1c733e719774038f8f4e4bb93194e358caa40
|
||||
F src/MainWindow.h 77038e9c9fe8a64a1c2dfb8d4c2be7558ab5f372
|
||||
F src/SettingsDialog.cpp 8fe0aacdca6694fe6711ec2b5ff4e54c7b426769
|
||||
F src/SettingsDialog.h 4e2790f581e991c744ae9f86580f1972b8c7ff43
|
||||
F src/Utils.cpp 9aff456712e4276b49083426301b3b96d3819c77
|
||||
F src/Utils.h c546e478a1225a28c99cd4c30f70cf9be9804a2a
|
||||
F src/main.cpp e1217b2331f1b0fd30756fc80a72f9676f09cf6b
|
||||
F tools/git-push.sh 62cc58434cae5b7bcd6bd9d4cce8b08739f31cd7 x
|
||||
F tools/pack.sh d7f38a498c4e9327fecd6a6e5ac27be270d43008 x
|
||||
F ui/AboutDialog.ui 77704a7422a59ccdddbdf00979bd20a861d9ee5a
|
||||
F ui/BrowserWidget.ui 994ad9ea0e9f5815d6b1a27acc2f6f39164c507f
|
||||
F ui/BrowserWidget.ui 5ad98b13773afadb20a1a2c22148aaebe5dbd95d
|
||||
F ui/CloneDialog.ui 4886e7d4f258ea8b852b5eefc860396e35145712
|
||||
F ui/CommitDialog.ui 1e5dafa742e9ae07ec937bcda8cda3297ddc6199
|
||||
F ui/CommitDialog.ui 6200f6cabdcf40a20812e811be28e0793f82516f
|
||||
F ui/FileActionDialog.ui 89bb4dc2d0b8adcd41adcb11ec65f2028a09a12d
|
||||
F ui/FslSettingsDialog.ui eb3d4cb764cab90b01e82922237d8c42d6ce1749
|
||||
F ui/MainWindow.ui e2a18caa7482b3ee0dff477592cdc9574b35fe4f
|
||||
F ui/RemoteDialog.ui 95a4750d972ed8c49bb10b95db91ff16cfe2dd0b
|
||||
F ui/RevisionDialog.ui 27c3b98c665fec014a50cbf3352c0627f75e68cd
|
||||
F ui/SettingsDialog.ui 2e1b6ce7a49100088c5649292c1319e62e0302e1
|
||||
P 8a83bfb691fc72a4208c24b547c9c38fc668ec97
|
||||
R 53814be492792eadbc8740da254dc306
|
||||
F ui/MainWindow.ui 8677f5c8bca5bf7561d5f64bfdd0cef5157c6ac7
|
||||
F ui/SettingsDialog.ui 2b7c2870e0054b0f4106f495d85d02c0b814df8b
|
||||
P f3d5c35a93cf7285b489307240a6b75fbc8cb3b8
|
||||
R d1cdbc42fc1a9f327c9de335a7e9bf81
|
||||
U kostas
|
||||
Z 50d6c6e9520bb3b791eaf9b75e5e6c9e
|
||||
Z 7390102f93cb735aad85da46b9b95e70
|
||||
|
@ -1 +1 @@
|
||||
3490f7140197453a7a45fea01b93281cf0c8ca3d
|
||||
2c6269f8f1b5cc9334488c2db77672deab813e1a
|
@ -1,28 +0,0 @@
|
||||
Icon Theme by Deleket - Jojo Mendoza
|
||||
Available under the CC Attribution Noncommercial No Derivative 3.0 License
|
||||
---------------------------------------
|
||||
|
||||
QtKeychain
|
||||
https://github.com/frankosterfeld/qtkeychain
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------
|
@ -1,10 +0,0 @@
|
||||
stayawake: de_DE
|
||||
djnavas: es_ES
|
||||
Fringale: fr_FR
|
||||
mouse166: ru_RU
|
||||
emansije: pt_PT
|
||||
maxxlupi: it_IT
|
||||
Zangune: it_IT
|
||||
Fly Man: nl_NL
|
||||
Rick Van Lieshout: nl_NL
|
||||
ardiefox: ko_KR
|
@ -4,40 +4,37 @@
|
||||
<file>icons/Adobe Illustrator CS3 Document-01.png</file>
|
||||
<file>icons/Adobe PDF Document-01.png</file>
|
||||
<file>icons/Adobe Photoshop CS3 Document-01.png</file>
|
||||
<file alias="icon-application">icons/Battery-01.png</file>
|
||||
<file>icons/Battery-01.png</file>
|
||||
<file>icons/Binoculars-01.png</file>
|
||||
<file alias="icon-item-tag">icons/Book-01.png</file>
|
||||
<file>icons/Book-01.png</file>
|
||||
<file>icons/Briefcase-01.png</file>
|
||||
<file alias="icon-item-added">icons/Button Add-01.png</file>
|
||||
<file>icons/Button Add-01.png</file>
|
||||
<file>icons/Button Blank Blue-01.png</file>
|
||||
<file alias="icon-item-unknown">icons/Button Blank Gray-01.png</file>
|
||||
<file alias="icon-item-unchanged">icons/Button Blank Green-01.png</file>
|
||||
<file alias="icon-item-conflicted">icons/Button Blank Red-01.png</file>
|
||||
<file alias="icon-item-edited">icons/Button Blank Yellow-01.png</file>
|
||||
<file>icons/Button Blank Gray-01.png</file>
|
||||
<file>icons/Button Blank Green-01.png</file>
|
||||
<file>icons/Button Blank Red-01.png</file>
|
||||
<file>icons/Button Blank Yellow-01.png</file>
|
||||
<file>icons/Button Cancel-01.png</file>
|
||||
<file alias="icon-item-deleted">icons/Button Close-01.png</file>
|
||||
<file alias="icon-action-tag-delete">icons/Button Close-01.png</file>
|
||||
<file alias="icon-action-stop">icons/Button Close-01.png</file>
|
||||
<file>icons/Button Close-01.png</file>
|
||||
<file>icons/Button Delete-01.png</file>
|
||||
<file alias="icon-action-pull">icons/Button Download-01.png</file>
|
||||
<file>icons/Button Download-01.png</file>
|
||||
<file>icons/Button Favorite-01.png</file>
|
||||
<file>icons/Button Forward-01.png</file>
|
||||
<file alias="icon-item-missing">icons/Button Help-01.png</file>
|
||||
<file>icons/Button Help-01.png</file>
|
||||
<file>icons/Button Info-01.png</file>
|
||||
<file>icons/Button Log Off-01.png</file>
|
||||
<file alias="icon-action-next">icons/Button Next-01.png</file>
|
||||
<file>icons/Button Next-01.png</file>
|
||||
<file>icons/Button Pause-01.png</file>
|
||||
<file alias="icon-action-update">icons/Button Play-01.png</file>
|
||||
<file alias="icon-action-previous">icons/Button Previous-01.png</file>
|
||||
<file alias="icon-action-refresh">icons/Button Refresh-01.png</file>
|
||||
<file alias="icon-action-undo">icons/Button Reload-01.png</file>
|
||||
<file alias="icon-item-renamed">icons/Button Reload-01.png</file>
|
||||
<file>icons/Button Play-01.png</file>
|
||||
<file>icons/Button Previous-01.png</file>
|
||||
<file>icons/Button Refresh-01.png</file>
|
||||
<file>icons/Button Reload-01.png</file>
|
||||
<file>icons/Button Reminder-01.png</file>
|
||||
<file alias="icon-action-revert">icons/Button Rewind-01.png</file>
|
||||
<file>icons/Button Rewind-01.png</file>
|
||||
<file>icons/Button Talk Balloon-01.png</file>
|
||||
<file alias="icon-action-quit">icons/Button Turn Off-01.png</file>
|
||||
<file>icons/Button Turn Off-01.png</file>
|
||||
<file>icons/Button Turn On-01.png</file>
|
||||
<file alias="icon-action-push">icons/Button Upload-01.png</file>
|
||||
<file>icons/Button Upload-01.png</file>
|
||||
<file>icons/Button Warning-01.png</file>
|
||||
<file>icons/Calculator-01.png</file>
|
||||
<file>icons/Calendar Blue-01.png</file>
|
||||
@ -45,28 +42,28 @@
|
||||
<file>icons/Calendar Red-01.png</file>
|
||||
<file>icons/Clipboard-01.png</file>
|
||||
<file>icons/Clipboard Paste-01.png</file>
|
||||
<file alias="icon-action-timeline">icons/Clock-01.png</file>
|
||||
<file>icons/Clock-01.png</file>
|
||||
<file>icons/Coin-01.png</file>
|
||||
<file>icons/Compressed File RAR-01.png</file>
|
||||
<file>icons/Compressed File SIT-01.png</file>
|
||||
<file>icons/Compressed File Zip-01.png</file>
|
||||
<file>icons/Computer Monitor-01.png</file>
|
||||
<file>icons/Computer Network-01.png</file>
|
||||
<file alias="icon-item-file">icons/Document-01.png</file>
|
||||
<file>icons/Document-01.png</file>
|
||||
<file>icons/Document Attach-01.png</file>
|
||||
<file alias="icon-action-repo-new">icons/Document Blank-01.png</file>
|
||||
<file>icons/Document Blank-01.png</file>
|
||||
<file>icons/Document Chart-01.png</file>
|
||||
<file alias="icon-item-diff">icons/Document Copy-01.png</file>
|
||||
<file alias="icon-action-merge">icons/Document Flow Chart-01.png</file>
|
||||
<file>icons/Document Copy-01.png</file>
|
||||
<file>icons/Document Flow Chart-01.png</file>
|
||||
<file>icons/Document Gant Chart-01.png</file>
|
||||
<file>icons/Document Help-01.png</file>
|
||||
<file>icons/Document Line Chart-01.png</file>
|
||||
<file>icons/Document Microsoft Excel-01.png</file>
|
||||
<file>icons/Document Microsoft PowerPoint-01.png</file>
|
||||
<file>icons/Document Microsoft Word-01.png</file>
|
||||
<file alias="icon-item-branch">icons/Document Organization Chart-01.png</file>
|
||||
<file>icons/Document Organization Chart-01.png</file>
|
||||
<file>icons/Document Preview-01.png</file>
|
||||
<file alias="icon-item-revert">icons/Document-Revert-icon.png</file>
|
||||
<file>icons/Document-Revert-icon.png</file>
|
||||
<file>icons/Document Text-01.png</file>
|
||||
<file>icons/Edit Document-01.png</file>
|
||||
<file>icons/Email-01.png</file>
|
||||
@ -81,33 +78,32 @@
|
||||
<file>icons/File Audio MP3-01.png</file>
|
||||
<file>icons/File Audio WAV-01.png</file>
|
||||
<file>icons/File Audio WMA-01.png</file>
|
||||
<file alias="icon-item-delete">icons/File Delete-01.png</file>
|
||||
<file alias="icon-item-history">icons/File History-01.png</file>
|
||||
<file alias="icon-item-add">icons/File New-01.png</file>
|
||||
<file alias="icon-item-rename">icons/File Open-01.png</file>
|
||||
<file>icons/File Delete-01.png</file>
|
||||
<file>icons/File History-01.png</file>
|
||||
<file>icons/File New-01.png</file>
|
||||
<file>icons/File Open-01.png</file>
|
||||
<file>icons/File Video 3GP-01.png</file>
|
||||
<file>icons/File Video-01.png</file>
|
||||
<file>icons/File Video AVI-01.png</file>
|
||||
<file>icons/File Video MOV-01.png</file>
|
||||
<file>icons/File Video MPEG-01.png</file>
|
||||
<file>icons/File Video WMV-01.png</file>
|
||||
<file alias="icon-item-folder">icons/Folder-01.png</file>
|
||||
<file alias="icon-action-stash-new">icons/Folder Add-01.png</file>
|
||||
<file alias="icon-action-stash-apply">icons/Folder Compressed-01.png</file>
|
||||
<file alias="icon-action-stash-delete">icons/Folder Delete-01.png</file>
|
||||
<file alias="icon-action-stash-diff">icons/Folder Explorer-01.png</file>
|
||||
<file alias="icon-action-folder-explore">icons/Folder Explorer-01.png</file>
|
||||
<file>icons/Folder-01.png</file>
|
||||
<file>icons/Folder Add-01.png</file>
|
||||
<file>icons/Folder Compressed-01.png</file>
|
||||
<file>icons/Folder Delete-01.png</file>
|
||||
<file>icons/Folder Explorer-01.png</file>
|
||||
<file>icons/Folder Generic Blue-01.png</file>
|
||||
<file alias="icon-item-folder-unchanged">icons/Folder Generic Green-01.png</file>
|
||||
<file alias="icon-item-folder-modified">icons/Folder Generic Red-01.png</file>
|
||||
<file alias="icon-item-folder-unknown">icons/Folder Generic Silver-01.png</file>
|
||||
<file alias="icon-action-folder-rename">icons/Folder Open-01.png</file>
|
||||
<file>icons/Folder Generic Green-01.png</file>
|
||||
<file>icons/Folder Generic Red-01.png</file>
|
||||
<file>icons/Folder Generic Silver-01.png</file>
|
||||
<file>icons/Folder Open-01.png</file>
|
||||
<file>icons/Folder RAR-01.png</file>
|
||||
<file>icons/Games-01.png</file>
|
||||
<file alias="icon-action-settings">icons/Gear-01.png</file>
|
||||
<file>icons/Gear-01.png</file>
|
||||
<file>icons/Highlighter Blue-01.png</file>
|
||||
<file>icons/Highlighter Green-01.png</file>
|
||||
<file alias="icon-action-tag-new">icons/Highlighter Yellow-01.png</file>
|
||||
<file>icons/Highlighter Yellow-01.png</file>
|
||||
<file>icons/Image BMP-01.png</file>
|
||||
<file>icons/Image GIF-01.png</file>
|
||||
<file>icons/Image JPEG-01.png</file>
|
||||
@ -115,21 +111,21 @@
|
||||
<file>icons/Image TIFF-01.png</file>
|
||||
<file>icons/Lock Lock-01.png</file>
|
||||
<file>icons/Lock Unlock-01.png</file>
|
||||
<file alias="icon-action-repo-open">icons/My Documents-01.png</file>
|
||||
<file>icons/My Documents-01.png</file>
|
||||
<file>icons/My Ebooks-01.png</file>
|
||||
<file>icons/My Music-01.png</file>
|
||||
<file>icons/My Pictures.png</file>
|
||||
<file>icons/My Videos-01.png</file>
|
||||
<file alias="icon-action-repo-clone">icons/My Websites-01.png</file>
|
||||
<file>icons/My Websites-01.png</file>
|
||||
<file>icons/Network Firewall-01.png</file>
|
||||
<file alias="icon-webview">icons/Network MAC-01.png</file>
|
||||
<file alias="icon-item-remote" >icons/Network PC-01.png</file>
|
||||
<file>icons/Network MAC-01.png</file>
|
||||
<file>icons/Network PC-01.png</file>
|
||||
<file>icons/Network Refresh-01.png</file>
|
||||
<file>icons/Pen Blue-01.png</file>
|
||||
<file>icons/Pen Green-01.png</file>
|
||||
<file>icons/Pen Red-01.png</file>
|
||||
<file alias="icon-action-commit">icons/Save-01.png</file>
|
||||
<file alias="icon-clear-log">icons/Text Edit.png</file>
|
||||
<file>icons/Save-01.png</file>
|
||||
<file>icons/Text Edit.png</file>
|
||||
<file>icons/USB-01.png</file>
|
||||
<file>icons/User Administrator Blue-01.png</file>
|
||||
<file>icons/User Administrator Green-01.png</file>
|
||||
@ -167,8 +163,4 @@
|
||||
<file>intl/nl_NL.qm</file>
|
||||
<file>intl/ko_KR.qm</file>
|
||||
</qresource>
|
||||
<qresource prefix="/docs">
|
||||
<file>docs/Translators.txt</file>
|
||||
<file>docs/Licenses.txt</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -1,41 +0,0 @@
|
||||
#include "AboutDialog.h"
|
||||
#include "ui_AboutDialog.h"
|
||||
#include <QFile>
|
||||
|
||||
AboutDialog::AboutDialog(QWidget *parent, const QString &fossilVersion) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AboutDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
QString banner(QCoreApplication::applicationName() + " " + QCoreApplication::applicationVersion());
|
||||
ui->lblBanner->setText(banner + "\n" + ui->lblBanner->text());
|
||||
|
||||
ui->lblQtVersion->setText(tr("QT version %0").arg(QT_VERSION_STR));
|
||||
|
||||
if(!fossilVersion.isEmpty())
|
||||
ui->lblFossilVersion->setText(tr("Fossil version %0").arg(fossilVersion));
|
||||
|
||||
QString additional;
|
||||
QFile ftrans(":/docs/docs/Translators.txt");
|
||||
if(ftrans.open(QFile::ReadOnly))
|
||||
{
|
||||
additional.append(tr("Translations with the help of:")+"\n");
|
||||
additional.append(ftrans.readAll());
|
||||
additional.append("\n\n");
|
||||
ftrans.close();
|
||||
}
|
||||
|
||||
QFile flicenses(":/docs/docs/Licenses.txt");
|
||||
if(flicenses.open(QFile::ReadOnly))
|
||||
{
|
||||
additional.append(tr("This sofware uses the following open-source libraries and assets:")+"\n");
|
||||
additional.append(flicenses.readAll());
|
||||
flicenses.close();
|
||||
}
|
||||
ui->txtAdditional->setText(additional);
|
||||
}
|
||||
|
||||
AboutDialog::~AboutDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#ifndef ABOUTDIALOG_H
|
||||
#define ABOUTDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class AboutDialog;
|
||||
}
|
||||
|
||||
class AboutDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AboutDialog(QWidget *parent, const QString &fossilVersion);
|
||||
~AboutDialog();
|
||||
|
||||
private:
|
||||
Ui::AboutDialog *ui;
|
||||
};
|
||||
|
||||
#endif // ABOUTDIALOG_H
|
@ -5,7 +5,6 @@
|
||||
#include <QMessageBox>
|
||||
#include <QClipboard>
|
||||
#include <QUrl>
|
||||
#include "Utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CloneDialog::CloneDialog(QWidget *parent) :
|
||||
@ -40,7 +39,7 @@ bool CloneDialog::run(QWidget *parent, QUrl &url, QString &repository, QUrl &url
|
||||
dlg.ui->linePassword->setText(nurl.password());
|
||||
nurl.setUserName("");
|
||||
nurl.setPassword("");
|
||||
dlg.ui->lineURL->setText(UrlToStringNoCredentials(nurl));
|
||||
dlg.ui->lineURL->setText(nurl.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,11 +90,6 @@ void CloneDialog::GetRepositoryPath(QString &pathResult)
|
||||
filter,
|
||||
&filter,
|
||||
QFileDialog::DontConfirmOverwrite);
|
||||
|
||||
// Ensure that it ends in the required extension (On GTK, Qt doesn't seem to add it automatically)
|
||||
QFileInfo fi(pathResult);
|
||||
if(fi.suffix().toLower() != ("." FOSSIL_EXT))
|
||||
pathResult += "." FOSSIL_EXT;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#define FOSSIL_CHECKOUT1 "_FOSSIL_"
|
||||
#define FOSSIL_CHECKOUT2 ".fslckout"
|
||||
#define FOSSIL_EXT "fossil"
|
||||
|
||||
namespace Ui {
|
||||
class CloneDialog;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "ui_CommitDialog.h"
|
||||
#include "MainWindow.h" // Ugly. I know.
|
||||
|
||||
CommitDialog::CommitDialog(QWidget *parent, const QString &title, QStringList &files, const QStringList *history, bool stashMode) :
|
||||
CommitDialog::CommitDialog(QWidget *parent, QString title, QStringList &files, const QStringList *history, bool singleLineEntry, const QString *checkBoxText, bool *checkBoxValue) :
|
||||
QDialog(parent, Qt::Sheet),
|
||||
ui(new Ui::CommitDialog)
|
||||
{
|
||||
@ -15,13 +15,16 @@ CommitDialog::CommitDialog(QWidget *parent, const QString &title, QStringList &f
|
||||
setWindowTitle(title);
|
||||
|
||||
// Activate the appropriate control based on mode
|
||||
ui->plainTextEdit->setVisible(!stashMode);
|
||||
ui->lineEdit->setVisible(stashMode);
|
||||
ui->plainTextEdit->setVisible(!singleLineEntry);
|
||||
ui->lineEdit->setVisible(singleLineEntry);
|
||||
|
||||
// Activate the checkbox if we have some text
|
||||
ui->chkRevertFiles->setVisible(stashMode);
|
||||
|
||||
ui->widgetBranchOptions->setVisible(!stashMode);
|
||||
ui->checkBox->setVisible(checkBoxText!=0);
|
||||
if(checkBoxText && checkBoxValue)
|
||||
{
|
||||
ui->checkBox->setText(*checkBoxText);
|
||||
ui->checkBox->setCheckState(*checkBoxValue ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
|
||||
// Activate the combo if we have history
|
||||
ui->comboBox->setVisible(history!=0);
|
||||
@ -74,13 +77,17 @@ CommitDialog::~CommitDialog()
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool CommitDialog::runCommit(QWidget* parent, QStringList& files, QString& commitMsg, const QStringList& commitMsgHistory, QString &branchName, bool &privateBranch)
|
||||
bool CommitDialog::run(QWidget *parent, QString title, QStringList &files, QString &commitMsg, const QStringList *history, bool singleLineEntry, const QString *checkBoxText, bool *checkBoxValue)
|
||||
{
|
||||
CommitDialog dlg(parent, tr("Commit Changes"), files, &commitMsgHistory, false);
|
||||
CommitDialog dlg(parent, title, files, history, singleLineEntry, checkBoxText, checkBoxValue);
|
||||
int res = dlg.exec();
|
||||
|
||||
if(singleLineEntry)
|
||||
commitMsg = dlg.ui->lineEdit->text();
|
||||
else
|
||||
commitMsg = dlg.ui->plainTextEdit->toPlainText();
|
||||
|
||||
|
||||
if(res!=QDialog::Accepted)
|
||||
return false;
|
||||
|
||||
@ -93,40 +100,15 @@ bool CommitDialog::runCommit(QWidget* parent, QStringList& files, QString& commi
|
||||
files.append(si->text());
|
||||
}
|
||||
|
||||
branchName.clear();
|
||||
if(dlg.ui->chkNewBranch->isChecked())
|
||||
if(checkBoxText)
|
||||
{
|
||||
branchName = dlg.ui->lineBranchName->text().trimmed();
|
||||
privateBranch = dlg.ui->chkPrivateBranch->isChecked();
|
||||
Q_ASSERT(checkBoxValue);
|
||||
*checkBoxValue = dlg.ui->checkBox->checkState() == Qt::Checked;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool CommitDialog::runStashNew(QWidget* parent, QStringList& stashedFiles, QString& stashName, bool& revertFiles)
|
||||
{
|
||||
CommitDialog dlg(parent, tr("Stash Changes"), stashedFiles, NULL, true);
|
||||
int res = dlg.exec();
|
||||
|
||||
stashName = dlg.ui->lineEdit->text();
|
||||
|
||||
if(res!=QDialog::Accepted)
|
||||
return false;
|
||||
|
||||
stashedFiles.clear();
|
||||
for(int i=0; i<dlg.itemModel.rowCount(); ++i)
|
||||
{
|
||||
QStandardItem *si = dlg.itemModel.item(i);
|
||||
if(si->checkState()!=Qt::Checked)
|
||||
continue;
|
||||
stashedFiles.append(si->text());
|
||||
}
|
||||
|
||||
revertFiles = dlg.ui->chkRevertFiles->checkState() == Qt::Checked;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void CommitDialog::on_comboBox_activated(int index)
|
||||
{
|
||||
@ -160,11 +142,3 @@ void CommitDialog::on_listView_clicked(const QModelIndex &)
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(num_selected>0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void CommitDialog::on_chkNewBranch_toggled(bool checked)
|
||||
{
|
||||
ui->lblPrivateBranch->setEnabled(checked);
|
||||
ui->chkPrivateBranch->setEnabled(checked);
|
||||
ui->lineBranchName->setEnabled(checked);
|
||||
}
|
||||
|
@ -13,17 +13,15 @@ class CommitDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CommitDialog(QWidget *parent, const QString &title, QStringList &files, const QStringList *history, bool stashMode);
|
||||
explicit CommitDialog(QWidget *parent, QString title, QStringList &files, const QStringList *history=0, bool singleLineEntry=false, const QString *checkBoxText=0, bool *checkBoxValue=0);
|
||||
~CommitDialog();
|
||||
|
||||
static bool runStashNew(QWidget* parent, QStringList& stashedFiles, QString& stashName, bool &revertFiles);
|
||||
static bool runCommit(QWidget* parent, QStringList& files, QString& commitMsg, const QStringList &commitMsgHistory, QString& branchName, bool& privateBranch);
|
||||
static bool run(QWidget *parent, QString title, QStringList &files, QString &commitMsg, const QStringList *history=0, bool singleLineEntry=false, const QString *checkBoxText=0, bool *checkBoxValue=0);
|
||||
|
||||
private slots:
|
||||
void on_comboBox_activated(int index);
|
||||
void on_listView_doubleClicked(const QModelIndex &index);
|
||||
void on_listView_clicked(const QModelIndex &index);
|
||||
void on_chkNewBranch_toggled(bool checked);
|
||||
|
||||
private:
|
||||
Ui::CommitDialog *ui;
|
||||
|
1175
src/Fossil.cpp
1175
src/Fossil.cpp
File diff suppressed because it is too large
Load Diff
152
src/Fossil.h
152
src/Fossil.h
@ -1,152 +0,0 @@
|
||||
#ifndef FOSSIL_H
|
||||
#define FOSSIL_H
|
||||
|
||||
class QStringList;
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
#include "LoggedProcess.h"
|
||||
#include "Utils.h"
|
||||
|
||||
typedef QMap<QString, QString> stashmap_t;
|
||||
|
||||
enum RunFlags
|
||||
{
|
||||
RUNFLAGS_NONE = 0<<0,
|
||||
RUNFLAGS_SILENT_INPUT = 1<<0,
|
||||
RUNFLAGS_SILENT_OUTPUT = 1<<1,
|
||||
RUNFLAGS_SILENT_ALL = RUNFLAGS_SILENT_INPUT | RUNFLAGS_SILENT_OUTPUT,
|
||||
RUNFLAGS_DETACHED = 1<<2,
|
||||
RUNFLAGS_DEBUG = 1<<3,
|
||||
};
|
||||
|
||||
enum RepoStatus
|
||||
{
|
||||
REPO_OK,
|
||||
REPO_NOT_FOUND,
|
||||
REPO_OLD_SCHEMA
|
||||
};
|
||||
|
||||
class Fossil
|
||||
{
|
||||
public:
|
||||
Fossil()
|
||||
: operationAborted(false)
|
||||
, uiCallback(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Init(UICallback *callback)
|
||||
{
|
||||
uiCallback = callback;
|
||||
fossilPath.clear();
|
||||
workspacePath.clear();
|
||||
}
|
||||
|
||||
bool runFossil(const QStringList &args, QStringList *output=0, int runFlags=RUNFLAGS_NONE);
|
||||
bool runFossilRaw(const QStringList &args, QStringList *output, int *exitCode, int runFlags);
|
||||
|
||||
static bool isWorkspace(const QString &path);
|
||||
|
||||
RepoStatus getRepoStatus();
|
||||
|
||||
void setWorkspacePath(const QString &workspace)
|
||||
{
|
||||
workspacePath = workspace;
|
||||
}
|
||||
|
||||
const QString &getWorkspacePath() const
|
||||
{
|
||||
return workspacePath;
|
||||
}
|
||||
|
||||
const QString &getProjectName() const
|
||||
{
|
||||
return projectName;
|
||||
}
|
||||
|
||||
const QString &getRepositoryFile() const
|
||||
{
|
||||
return repositoryFile;
|
||||
}
|
||||
|
||||
void setRepositoryFile(const QString &filename)
|
||||
{
|
||||
repositoryFile = filename;
|
||||
}
|
||||
|
||||
bool openRepository(const QString &repositoryPath, const QString& workspacePath);
|
||||
bool newRepository(const QString &repositoryPath);
|
||||
bool closeRepository();
|
||||
bool pushRepository(const QUrl& url);
|
||||
bool pullRepository(const QUrl& url);
|
||||
bool cloneRepository(const QString &repository, const QUrl &url, const QUrl &proxyUrl);
|
||||
bool undoRepository(QStringList& result, bool explainOnly);
|
||||
bool updateRepository(QStringList& result, const QString& revision, bool explainOnly);
|
||||
bool getFossilVersion(QString &version);
|
||||
|
||||
bool uiRunning() const;
|
||||
bool startUI(const QString &httpPort);
|
||||
void stopUI();
|
||||
|
||||
bool listFiles(QStringList &files);
|
||||
bool status(QStringList& result);
|
||||
|
||||
bool diffFile(const QString &repoFile, bool graphical);
|
||||
bool commitFiles(const QStringList &fileList, const QString &comment, const QString& newBranchName, bool isPrivateBranch);
|
||||
bool addFiles(const QStringList& fileList);
|
||||
bool removeFiles(const QStringList& fileList, bool deleteLocal);
|
||||
bool revertFiles(const QStringList& fileList);
|
||||
bool renameFile(const QString& beforePath, const QString& afterPath, bool renameLocal);
|
||||
bool getFossilSettings(QStringList& result);
|
||||
bool setFossilSetting(const QString &name, const QString &value, bool global);
|
||||
bool setRemoteUrl(const QUrl& url);
|
||||
bool getRemoteUrl(QUrl &url);
|
||||
|
||||
bool stashNew(const QStringList& fileList, const QString& name, bool revert);
|
||||
bool stashList(stashmap_t &stashes);
|
||||
bool stashApply(const QString& name);
|
||||
bool stashDrop(const QString& name);
|
||||
bool stashDiff(const QString& name);
|
||||
|
||||
void abortOperation() { operationAborted = true; }
|
||||
|
||||
bool tagList(QStringMap& tags);
|
||||
bool tagNew(const QString& name, const QString& revision);
|
||||
bool tagDelete(const QString& name, const QString& revision);
|
||||
|
||||
bool branchList(QStringList& branches, QStringList& activeBranches);
|
||||
bool branchNew(const QString& name, const QString& revisionBasis, bool isPrivate=false);
|
||||
bool branchMerge(QStringList& res, const QString& revision, bool integrate, bool force, bool testOnly);
|
||||
|
||||
const QString &getCurrentRevision() const { return currentRevision; }
|
||||
const QStringList &getActiveTags() const { return activeTags; }
|
||||
|
||||
const QString &getUIHttpPort() const { return fossilUIPort; }
|
||||
QString getUIHttpAddress() const;
|
||||
|
||||
void setExecutablePath(const QString &path) { fossilPath = path; }
|
||||
|
||||
private:
|
||||
void log(const QString &text, bool isHTML=false)
|
||||
{
|
||||
if(uiCallback)
|
||||
uiCallback->logText(text, isHTML);
|
||||
}
|
||||
|
||||
QString getFossilPath();
|
||||
|
||||
bool operationAborted;
|
||||
UICallback *uiCallback;
|
||||
QString workspacePath;
|
||||
QString fossilPath; // The value from the settings
|
||||
QString repositoryFile;
|
||||
QString projectName;
|
||||
QString currentRevision;
|
||||
QStringList activeTags;
|
||||
LoggedProcess fossilUI;
|
||||
QString fossilUIPort;
|
||||
};
|
||||
|
||||
|
||||
#endif // FOSSIL_H
|
@ -1,70 +0,0 @@
|
||||
#include "FslSettingsDialog.h"
|
||||
#include "ui_FslSettingsDialog.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
FslSettingsDialog::FslSettingsDialog(QWidget *parent, Settings &_settings) :
|
||||
QDialog(parent, Qt::Sheet),
|
||||
ui(new Ui::FslSettingsDialog),
|
||||
settings(&_settings)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->lineUIPort->setText(settings->GetFossilValue(FOSSIL_SETTING_HTTP_PORT).toString());
|
||||
|
||||
// Global Settings
|
||||
ui->lineGDiffCommand->setText(settings->GetFossilValue(FOSSIL_SETTING_GDIFF_CMD).toString());
|
||||
ui->lineGMergeCommand->setText(settings->GetFossilValue(FOSSIL_SETTING_GMERGE_CMD).toString());
|
||||
ui->lineProxy->setText(settings->GetFossilValue(FOSSIL_SETTING_PROXY_URL).toString());
|
||||
|
||||
// Repository Settings
|
||||
ui->lineIgnore->setText(settings->GetFossilValue(FOSSIL_SETTING_IGNORE_GLOB).toString());
|
||||
ui->lineIgnoreCRNL->setText(settings->GetFossilValue(FOSSIL_SETTING_CRNL_GLOB).toString());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
FslSettingsDialog::~FslSettingsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool FslSettingsDialog::run(QWidget *parent, Settings &settings)
|
||||
{
|
||||
FslSettingsDialog dlg(parent, settings);
|
||||
return dlg.exec() == QDialog::Accepted;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void FslSettingsDialog::on_buttonBox_accepted()
|
||||
{
|
||||
settings->SetFossilValue(FOSSIL_SETTING_HTTP_PORT, ui->lineUIPort->text());
|
||||
|
||||
settings->SetFossilValue(FOSSIL_SETTING_GDIFF_CMD, ui->lineGDiffCommand->text());
|
||||
settings->SetFossilValue(FOSSIL_SETTING_GMERGE_CMD, ui->lineGMergeCommand->text());
|
||||
settings->SetFossilValue(FOSSIL_SETTING_PROXY_URL, ui->lineProxy->text());
|
||||
|
||||
settings->SetFossilValue(FOSSIL_SETTING_IGNORE_GLOB, ui->lineIgnore->text());
|
||||
settings->SetFossilValue(FOSSIL_SETTING_CRNL_GLOB, ui->lineIgnoreCRNL->text());
|
||||
|
||||
settings->ApplyEnvironment();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void FslSettingsDialog::on_btnSelectFossilGDiff_clicked()
|
||||
{
|
||||
QString path = SelectExe(this, tr("Select Graphical Diff application"));
|
||||
if(!path.isEmpty())
|
||||
ui->lineGDiffCommand->setText(QDir::toNativeSeparators(path));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void FslSettingsDialog::on_btnSelectGMerge_clicked()
|
||||
{
|
||||
QString path = SelectExe(this, tr("Select Graphical Merge application"));
|
||||
if(!path.isEmpty())
|
||||
ui->lineGMergeCommand->setText(path);
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
#ifndef FSLSETTINGSDIALOG_H
|
||||
#define FSLSETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "Settings.h"
|
||||
|
||||
namespace Ui {
|
||||
class FslSettingsDialog;
|
||||
}
|
||||
|
||||
class FslSettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FslSettingsDialog(QWidget *parent, Settings &_settings);
|
||||
~FslSettingsDialog();
|
||||
|
||||
static bool run(QWidget *parent, Settings &_settings);
|
||||
|
||||
|
||||
private slots:
|
||||
void on_buttonBox_accepted();
|
||||
void on_btnSelectFossilGDiff_clicked();
|
||||
void on_btnSelectGMerge_clicked();
|
||||
|
||||
private:
|
||||
|
||||
Ui::FslSettingsDialog *ui;
|
||||
Settings *settings;
|
||||
};
|
||||
|
||||
#endif // FSLSETTINGSDIALOG_H
|
2596
src/MainWindow.cpp
2596
src/MainWindow.cpp
File diff suppressed because it is too large
Load Diff
253
src/MainWindow.h
253
src/MainWindow.h
@ -2,15 +2,114 @@
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QStandardItemModel>
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QProcess>
|
||||
#include <QFileIconProvider>
|
||||
#include "Settings.h"
|
||||
#include "Workspace.h"
|
||||
#include <QSet>
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
|
||||
class QStringList;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// RepoFile
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct RepoFile
|
||||
{
|
||||
enum EntryType
|
||||
{
|
||||
TYPE_UNKNOWN = 1<<0,
|
||||
TYPE_UNCHANGED = 1<<1,
|
||||
TYPE_EDITTED = 1<<2,
|
||||
TYPE_ADDED = 1<<3,
|
||||
TYPE_DELETED = 1<<4,
|
||||
TYPE_MISSING = 1<<5,
|
||||
TYPE_RENAMED = 1<<6,
|
||||
TYPE_CONFLICTED = 1<<7,
|
||||
TYPE_MODIFIED = TYPE_EDITTED|TYPE_ADDED|TYPE_DELETED|TYPE_MISSING|TYPE_RENAMED|TYPE_CONFLICTED,
|
||||
TYPE_REPO = TYPE_UNCHANGED|TYPE_MODIFIED,
|
||||
TYPE_ALL = TYPE_UNKNOWN|TYPE_REPO
|
||||
};
|
||||
|
||||
RepoFile(QFileInfo &info, EntryType type, const QString &repoPath)
|
||||
{
|
||||
FileInfo = info;
|
||||
Type = type;
|
||||
FilePath = getRelativeFilename(repoPath);
|
||||
Path = FileInfo.absolutePath();
|
||||
|
||||
// Strip the workspace path from the path
|
||||
Q_ASSERT(Path.indexOf(repoPath)==0);
|
||||
Path = Path.mid(repoPath.length()+1);
|
||||
}
|
||||
|
||||
bool isType(EntryType t) const
|
||||
{
|
||||
return Type == t;
|
||||
}
|
||||
|
||||
void setType(EntryType t)
|
||||
{
|
||||
Type = t;
|
||||
}
|
||||
|
||||
EntryType getType() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
QFileInfo getFileInfo() const
|
||||
{
|
||||
return FileInfo;
|
||||
}
|
||||
|
||||
bool isRepo() const
|
||||
{
|
||||
return Type == TYPE_UNCHANGED || Type == TYPE_EDITTED;
|
||||
}
|
||||
|
||||
const QString &getFilePath() const
|
||||
{
|
||||
return FilePath;
|
||||
}
|
||||
|
||||
QString getFilename() const
|
||||
{
|
||||
return FileInfo.fileName();
|
||||
}
|
||||
|
||||
const QString &getPath() const
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
|
||||
QString getRelativeFilename(const QString &path)
|
||||
{
|
||||
QString abs_base_dir = QDir(path).absolutePath();
|
||||
|
||||
QString relative = FileInfo.absoluteFilePath();
|
||||
int index = relative.indexOf(abs_base_dir);
|
||||
if(index<0)
|
||||
return QString("");
|
||||
|
||||
return relative.right(relative.length() - abs_base_dir.length()-1);
|
||||
}
|
||||
|
||||
private:
|
||||
QFileInfo FileInfo;
|
||||
EntryType Type;
|
||||
QString FilePath;
|
||||
QString Path;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MainWindow
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -21,47 +120,67 @@ class MainWindow : public QMainWindow
|
||||
public:
|
||||
explicit MainWindow(Settings &_settings, QWidget *parent = 0, QString *workspacePath = 0);
|
||||
~MainWindow();
|
||||
bool diffFile(const QString& repoFile);
|
||||
bool diffFile(QString repoFile);
|
||||
void fullRefresh();
|
||||
|
||||
private:
|
||||
typedef QSet<QString> stringset_t;
|
||||
enum RunFlags
|
||||
{
|
||||
RUNFLAGS_NONE = 0<<0,
|
||||
RUNFLAGS_SILENT_INPUT = 1<<0,
|
||||
RUNFLAGS_SILENT_OUTPUT = 1<<1,
|
||||
RUNFLAGS_SILENT_ALL = RUNFLAGS_SILENT_INPUT | RUNFLAGS_SILENT_OUTPUT,
|
||||
RUNFLAGS_DETACHED = 1<<2
|
||||
};
|
||||
|
||||
private:
|
||||
bool refresh();
|
||||
void scanWorkspace();
|
||||
bool runFossil(const QStringList &args, QStringList *output=0, int runFlags=RUNFLAGS_NONE);
|
||||
bool runFossilRaw(const QStringList &args, QStringList *output=0, int *exitCode=0, int runFlags=RUNFLAGS_NONE);
|
||||
void applySettings();
|
||||
void updateSettings();
|
||||
void updateRevision(const QString& revision);
|
||||
const QString &getCurrentWorkspace();
|
||||
void setCurrentWorkspace(const QString &workspace);
|
||||
void log(const QString &text, bool isHTML=false);
|
||||
void setStatus(const QString &text);
|
||||
bool uiRunning() const;
|
||||
void getSelectionFilenames(QStringList &filenames, int includeMask=WorkspaceFile::TYPE_ALL, bool allIfEmpty=false);
|
||||
void getFileViewSelection(QStringList &filenames, int includeMask=WorkspaceFile::TYPE_ALL, bool allIfEmpty=false);
|
||||
void getDirViewSelection(QStringList &filenames, int includeMask=WorkspaceFile::TYPE_ALL, bool allIfEmpty=false);
|
||||
void getSelectionStashes(QStringList &stashNames);
|
||||
bool uiRunning() const { return fossilUI.state() == QProcess::Running; }
|
||||
void getSelectionFilenames(QStringList &filenames, int includeMask=RepoFile::TYPE_ALL, bool allIfEmpty=false);
|
||||
void getFileViewSelection(QStringList &filenames, int includeMask=RepoFile::TYPE_ALL, bool allIfEmpty=false);
|
||||
void getDirViewSelection(QStringList &filenames, int includeMask=RepoFile::TYPE_ALL, bool allIfEmpty=false);
|
||||
void getStashViewSelection(QStringList &stashNames, bool allIfEmpty=false);
|
||||
void getSelectionPaths(stringset_t &paths);
|
||||
void getSelectionRemotes(QStringList& remoteUrls);
|
||||
void getAllFilenames(QStringList &filenames, int includeMask=WorkspaceFile::TYPE_ALL);
|
||||
void getAllFilenames(QStringList &filenames, int includeMask=RepoFile::TYPE_ALL);
|
||||
bool startUI();
|
||||
void stopUI();
|
||||
void enableActions(bool on);
|
||||
void addWorkspaceHistory(const QString &dir);
|
||||
void addWorkspace(const QString &dir);
|
||||
void rebuildRecent();
|
||||
bool openWorkspace(const QString &path);
|
||||
void loadFossilSettings();
|
||||
void updateWorkspaceView();
|
||||
QString getFossilPath();
|
||||
QString getFossilHttpAddress();
|
||||
bool scanDirectory(QFileInfoList &entries, const QString& dirPath, const QString &baseDir, const QString ignoreSpec, const bool& abort);
|
||||
void updateDirView();
|
||||
void updateFileView();
|
||||
void updateStashView();
|
||||
void selectRootDir();
|
||||
void mergeRevision(const QString& defaultRevision);
|
||||
void updateCustomActions();
|
||||
void invokeCustomAction(int actionId);
|
||||
|
||||
void fossilBrowse(const QString &fossilUrl);
|
||||
void dragEnterEvent(class QDragEnterEvent *event);
|
||||
void dropEvent(class QDropEvent *event);
|
||||
void setBusy(bool busy);
|
||||
virtual QMenu *createPopupMenu();
|
||||
const QIcon& getCachedIcon(const char *name);
|
||||
const QIcon& getCachedFileIcon(const QFileInfo &finfo);
|
||||
const QIcon& getInternalIcon(const char *name);
|
||||
|
||||
enum RepoStatus
|
||||
{
|
||||
REPO_OK,
|
||||
REPO_NOT_FOUND,
|
||||
REPO_OLD_SCHEMA
|
||||
};
|
||||
|
||||
RepoStatus getRepoStatus();
|
||||
|
||||
enum ViewMode
|
||||
{
|
||||
@ -73,12 +192,9 @@ private slots:
|
||||
// Manual slots.
|
||||
// Use a different naming scheme to prevent warnings from Qt's automatic signaling
|
||||
void onOpenRecent();
|
||||
void onWorkspaceTreeViewSelectionChanged(const class QItemSelection &selected, const class QItemSelection &deselected);
|
||||
void onTreeViewSelectionChanged(const class QItemSelection &selected, const class QItemSelection &deselected);
|
||||
void onFileViewDragOut();
|
||||
void onAbort();
|
||||
void onSearchBoxTextChanged(const QString &text);
|
||||
void onSearch();
|
||||
void onCustomActionTriggered();
|
||||
|
||||
// Designer slots
|
||||
void on_actionRefresh_triggered();
|
||||
@ -88,13 +204,11 @@ private slots:
|
||||
void on_actionTimeline_triggered();
|
||||
void on_actionHistory_triggered();
|
||||
void on_actionClearLog_triggered();
|
||||
void on_fileTableView_doubleClicked(const QModelIndex &index);
|
||||
void on_workspaceTreeView_doubleClicked(const QModelIndex &index);
|
||||
void on_tableView_doubleClicked(const QModelIndex &index);
|
||||
void on_treeView_doubleClicked(const QModelIndex &index);
|
||||
void on_actionOpenFile_triggered();
|
||||
void on_actionPush_triggered();
|
||||
void on_actionPull_triggered();
|
||||
void on_actionPushRemote_triggered();
|
||||
void on_actionPullRemote_triggered();
|
||||
void on_actionCommit_triggered();
|
||||
void on_actionAdd_triggered();
|
||||
void on_actionDelete_triggered();
|
||||
@ -105,62 +219,26 @@ private slots:
|
||||
void on_actionAbout_triggered();
|
||||
void on_actionUpdate_triggered();
|
||||
void on_actionSettings_triggered();
|
||||
void on_actionFossilSettings_triggered();
|
||||
void on_actionViewUnchanged_triggered();
|
||||
void on_actionViewModified_triggered();
|
||||
void on_actionViewUnknown_triggered();
|
||||
void on_actionViewIgnored_triggered();
|
||||
void on_actionViewAll_triggered();
|
||||
void on_actionViewModifedOnly_triggered();
|
||||
void on_actionViewAsList_triggered();
|
||||
void on_actionViewAsFolders_triggered();
|
||||
void on_actionOpenFolder_triggered();
|
||||
void on_actionRenameFolder_triggered();
|
||||
void on_actionNewRepository_triggered();
|
||||
void on_actionOpenRepository_triggered();
|
||||
void on_actionCloseRepository_triggered();
|
||||
void on_actionCloneRepository_triggered();
|
||||
void on_actionCreateStash_triggered();
|
||||
void on_actionViewStash_triggered();
|
||||
void on_actionNewStash_triggered();
|
||||
void on_actionApplyStash_triggered();
|
||||
void on_actionDeleteStash_triggered();
|
||||
void on_actionDiffStash_triggered();
|
||||
void on_textBrowser_customContextMenuRequested(const QPoint &pos);
|
||||
void on_fileTableView_customContextMenuRequested(const QPoint &pos);
|
||||
void on_workspaceTreeView_customContextMenuRequested(const QPoint &pos);
|
||||
void on_actionCreateTag_triggered();
|
||||
void on_actionDeleteTag_triggered();
|
||||
void on_actionCreateBranch_triggered();
|
||||
void on_actionMergeBranch_triggered();
|
||||
void on_actionEditRemote_triggered();
|
||||
void on_actionSetDefaultRemote_triggered();
|
||||
void on_actionAddRemote_triggered();
|
||||
void on_actionDeleteRemote_triggered();
|
||||
void on_tableView_customContextMenuRequested(const QPoint &pos);
|
||||
|
||||
private:
|
||||
class MainWinUICallback : public UICallback
|
||||
{
|
||||
public:
|
||||
MainWinUICallback() : mainWindow(0)
|
||||
{}
|
||||
|
||||
void init(class MainWindow *mainWindow)
|
||||
{
|
||||
this->mainWindow = mainWindow;
|
||||
}
|
||||
|
||||
virtual void logText(const QString& text, bool isHTML);
|
||||
virtual void beginProcess(const QString& text);
|
||||
virtual void updateProcess(const QString& text);
|
||||
virtual void endProcess();
|
||||
virtual QMessageBox::StandardButton Query(const QString &title, const QString &query, QMessageBox::StandardButtons buttons);
|
||||
|
||||
|
||||
private:
|
||||
class MainWindow *mainWindow;
|
||||
};
|
||||
|
||||
friend class MainWinUICallback;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_RECENT=5
|
||||
@ -171,39 +249,30 @@ private:
|
||||
Ui::MainWindow *ui;
|
||||
QFileIconProvider iconProvider;
|
||||
icon_map_t iconCache;
|
||||
QStandardItemModel repoFileModel;
|
||||
QStandardItemModel repoDirModel;
|
||||
QStandardItemModel repoStashModel;
|
||||
QProcess fossilUI;
|
||||
class QAction *recentWorkspaceActs[MAX_RECENT];
|
||||
class QAction *customActions[MAX_CUSTOM_ACTIONS];
|
||||
class QAction *fileActionSeparator;
|
||||
class QAction *workspaceActionSeparator;
|
||||
class QProgressBar *progressBar;
|
||||
class QLabel *lblTags;
|
||||
class QShortcut *abortShortcut;
|
||||
class SearchBox *searchBox;
|
||||
class QShortcut *searchShortcut;
|
||||
QMenu *menuWorkspace;
|
||||
QMenu *menuStashes;
|
||||
QMenu *menuTags;
|
||||
QMenu *menuBranches;
|
||||
QMenu *menuRemotes;
|
||||
|
||||
bool operationAborted;
|
||||
stringset_t selectedDirs; // The directory selected in the tree
|
||||
QStringList selectedTags;
|
||||
QStringList selectedBranches;
|
||||
QStringList versionList;
|
||||
|
||||
Workspace workspace;
|
||||
Workspace & getWorkspace() { return workspace; }
|
||||
|
||||
Fossil & fossil() { return workspace.fossil(); }
|
||||
const Fossil & fossil() const { return workspace.fossil(); }
|
||||
bool abortOperation;
|
||||
|
||||
Settings &settings;
|
||||
QString projectName;
|
||||
QString repositoryFile;
|
||||
QStringList workspaceHistory;
|
||||
|
||||
MainWinUICallback uiCallback;
|
||||
|
||||
QString currentWorkspace;
|
||||
ViewMode viewMode;
|
||||
stringset_t selectedDirs; // The directory selected in the tree
|
||||
|
||||
// Repository State
|
||||
typedef QList<RepoFile*> filelist_t;
|
||||
typedef QMap<QString, RepoFile*> filemap_t;
|
||||
typedef QMap<QString, QString> stashmap_t;
|
||||
filemap_t workspaceFiles;
|
||||
stringset_t pathSet;
|
||||
stashmap_t stashMap;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -1,95 +0,0 @@
|
||||
#include "RemoteDialog.h"
|
||||
#include "ui_RemoteDialog.h"
|
||||
#include <QFileDialog>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QClipboard>
|
||||
#include <QUrl>
|
||||
#include "Utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
RemoteDialog::RemoteDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::RemoteDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
RemoteDialog::~RemoteDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RemoteDialog::run(QWidget *parent, QUrl &url, QString &name)
|
||||
{
|
||||
RemoteDialog dlg(parent);
|
||||
|
||||
// Set URL components
|
||||
if(!url.isEmpty())
|
||||
{
|
||||
QString url_no_credentials = UrlToStringNoCredentials(url);
|
||||
dlg.ui->lineURL->setText(url_no_credentials);
|
||||
dlg.ui->lineUserName->setText(url.userName());
|
||||
dlg.ui->linePassword->setText(url.password());
|
||||
dlg.ui->lineName->setText(name);
|
||||
}
|
||||
|
||||
if(dlg.exec() != QDialog::Accepted)
|
||||
return false;
|
||||
|
||||
QString urltext = dlg.ui->lineURL->text();
|
||||
|
||||
url = QUrl::fromUserInput(urltext);
|
||||
if(url.isEmpty() || !url.isValid())
|
||||
{
|
||||
QMessageBox::critical(parent, tr("Error"), tr("Invalid URL."), QMessageBox::Ok );
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!dlg.ui->lineUserName->text().trimmed().isEmpty())
|
||||
url.setUserName(dlg.ui->lineUserName->text());
|
||||
|
||||
if(!dlg.ui->linePassword->text().trimmed().isEmpty())
|
||||
url.setPassword(dlg.ui->linePassword->text());
|
||||
|
||||
name =dlg.ui->lineName->text().trimmed();
|
||||
if(name.isEmpty())
|
||||
name = UrlToStringNoCredentials(url);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RemoteDialog::GetRepositoryPath(QString &pathResult)
|
||||
{
|
||||
QString filter(tr("Fossil Repository") + QString(" (*." FOSSIL_EXT ")"));
|
||||
|
||||
pathResult = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
tr("Select Fossil Repository"),
|
||||
QDir::toNativeSeparators(pathResult),
|
||||
filter,
|
||||
&filter,
|
||||
QFileDialog::DontConfirmOverwrite);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RemoteDialog::on_btnSelectSourceRepo_clicked()
|
||||
{
|
||||
QString path = ui->lineURL->text();
|
||||
GetRepositoryPath(path);
|
||||
|
||||
if(path.trimmed().isEmpty())
|
||||
return;
|
||||
|
||||
if(!QFile::exists(path))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Invalid Repository File."), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
ui->lineURL->setText(QDir::toNativeSeparators(path));
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
#ifndef REMOTEDIALOG_H
|
||||
#define REMOTEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class RemoteDialog;
|
||||
}
|
||||
|
||||
class RemoteDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RemoteDialog(QWidget *parent = 0);
|
||||
~RemoteDialog();
|
||||
|
||||
static bool run(QWidget *parent, class QUrl &url, QString &name);
|
||||
|
||||
private slots:
|
||||
void on_btnSelectSourceRepo_clicked();
|
||||
|
||||
private:
|
||||
void GetRepositoryPath(QString &pathResult);
|
||||
|
||||
Ui::RemoteDialog *ui;
|
||||
};
|
||||
|
||||
#endif // REMOTEDIALOG_H
|
@ -1,100 +0,0 @@
|
||||
#include "RevisionDialog.h"
|
||||
#include "ui_RevisionDialog.h"
|
||||
#include "Utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
RevisionDialog::RevisionDialog(QWidget *parent, const QStringList &completions, const QString &defaultValue) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::RevisionDialog),
|
||||
completer(completions, parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->cmbRevision->setCompleter(&completer);
|
||||
|
||||
ui->cmbRevision->addItems(completions);
|
||||
|
||||
if(!defaultValue.isEmpty())
|
||||
{
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||||
int index = ui->cmbRevision->findText(defaultValue);
|
||||
if(index>=0)
|
||||
ui->cmbRevision->setCurrentIndex(index);
|
||||
#else
|
||||
ui->cmbRevision->setCurrentText(defaultValue);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
RevisionDialog::~RevisionDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
QString RevisionDialog::runUpdate(QWidget *parent, const QString &title, const QStringList &completions, const QString &defaultValue)
|
||||
{
|
||||
RevisionDialog dlg(parent, completions, defaultValue);
|
||||
dlg.setWindowTitle(title);
|
||||
dlg.ui->lblName->setVisible(false);
|
||||
dlg.ui->lineName->setVisible(false);
|
||||
dlg.ui->lblIntegrate->setVisible(false);
|
||||
dlg.ui->chkIntegrate->setVisible(false);
|
||||
dlg.ui->lblForce->setVisible(false);
|
||||
dlg.ui->chkForce->setVisible(false);
|
||||
|
||||
dlg.adjustSize();
|
||||
|
||||
if(dlg.exec() != QDialog::Accepted)
|
||||
return QString("");
|
||||
return dlg.ui->cmbRevision->currentText().trimmed();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
QString RevisionDialog::runMerge(QWidget *parent, const QString &title, const QStringList &completions, const QString &defaultValue, bool &integrate, bool &force)
|
||||
{
|
||||
RevisionDialog dlg(parent, completions, defaultValue);
|
||||
dlg.setWindowTitle(title);
|
||||
dlg.ui->lblName->setVisible(false);
|
||||
dlg.ui->lineName->setVisible(false);
|
||||
dlg.ui->lblIntegrate->setVisible(true);
|
||||
dlg.ui->chkIntegrate->setVisible(true);
|
||||
dlg.ui->chkIntegrate->setChecked(integrate);
|
||||
dlg.ui->lblForce->setVisible(true);
|
||||
dlg.ui->chkForce->setVisible(true);
|
||||
dlg.ui->chkForce->setChecked(force);
|
||||
|
||||
dlg.adjustSize();
|
||||
|
||||
if(dlg.exec() != QDialog::Accepted)
|
||||
return QString("");
|
||||
|
||||
integrate = dlg.ui->chkIntegrate->checkState() == Qt::Checked;
|
||||
force = dlg.ui->chkForce->checkState() == Qt::Checked;
|
||||
|
||||
return dlg.ui->cmbRevision->currentText().trimmed();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RevisionDialog::runNewTag(QWidget *parent, const QString &title, const QStringList &completions, const QString &defaultValue, QString &revision, QString &name)
|
||||
{
|
||||
RevisionDialog dlg(parent, completions, defaultValue);
|
||||
dlg.setWindowTitle(title);
|
||||
|
||||
dlg.ui->lblName->setVisible(true);
|
||||
dlg.ui->lineName->setVisible(true);
|
||||
dlg.ui->lblIntegrate->setVisible(false);
|
||||
dlg.ui->chkIntegrate->setVisible(false);
|
||||
dlg.ui->lblForce->setVisible(false);
|
||||
dlg.ui->chkForce->setVisible(false);
|
||||
|
||||
dlg.adjustSize();
|
||||
|
||||
if(dlg.exec() != QDialog::Accepted)
|
||||
return false;
|
||||
|
||||
revision = dlg.ui->cmbRevision->currentText().trimmed();
|
||||
name = dlg.ui->lineName->text().trimmed();
|
||||
return true;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#ifndef REVISIONDIALOG_H
|
||||
#define REVISIONDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QCompleter>
|
||||
|
||||
namespace Ui {
|
||||
class RevisionDialog;
|
||||
}
|
||||
|
||||
class RevisionDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RevisionDialog(QWidget *parent, const QStringList &completions, const QString &defaultValue);
|
||||
~RevisionDialog();
|
||||
|
||||
static QString runUpdate(QWidget *parent, const QString &title, const QStringList &completions, const QString &defaultValue);
|
||||
static QString runMerge(QWidget* parent, const QString& title, const QStringList& completions, const QString& defaultValue, bool& integrate, bool& force);
|
||||
static bool runNewTag(QWidget *parent, const QString &title, const QStringList &completions, const QString &defaultValue, QString &revision, QString &name);
|
||||
|
||||
private:
|
||||
Ui::RevisionDialog *ui;
|
||||
QCompleter completer;
|
||||
};
|
||||
|
||||
#endif // REVISIONDIALOG_H
|
@ -1,24 +0,0 @@
|
||||
#include "SearchBox.h"
|
||||
#include <QKeyEvent>
|
||||
|
||||
SearchBox::SearchBox(QWidget *parent) : QLineEdit(parent)
|
||||
{
|
||||
}
|
||||
|
||||
SearchBox::~SearchBox()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SearchBox::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
// Clear text on escape
|
||||
if(event->key() == Qt::Key_Escape)
|
||||
{
|
||||
setText("");
|
||||
clearFocus();
|
||||
}
|
||||
else
|
||||
QLineEdit::keyPressEvent(event);
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
#ifndef SEARCHBOX_H
|
||||
#define SEARCHBOX_H
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
class SearchBox : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SearchBox(QWidget* parent=0);
|
||||
~SearchBox();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // SEARCHBOX_H
|
131
src/Settings.cpp
131
src/Settings.cpp
@ -1,131 +0,0 @@
|
||||
#include "Settings.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QTranslator>
|
||||
#include <QResource>
|
||||
#include <QTextCodec>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Settings::Settings(bool portableMode) : store(0)
|
||||
{
|
||||
Mappings.insert(FOSSIL_SETTING_GDIFF_CMD, Setting("", Setting::TYPE_FOSSIL_GLOBAL));
|
||||
Mappings.insert(FOSSIL_SETTING_GMERGE_CMD, Setting("", Setting::TYPE_FOSSIL_GLOBAL));
|
||||
Mappings.insert(FOSSIL_SETTING_PROXY_URL, Setting("", Setting::TYPE_FOSSIL_GLOBAL));
|
||||
Mappings.insert(FOSSIL_SETTING_HTTP_PORT, Setting("", Setting::TYPE_FOSSIL_GLOBAL));
|
||||
|
||||
Mappings.insert(FOSSIL_SETTING_IGNORE_GLOB, Setting("", Setting::TYPE_FOSSIL_LOCAL));
|
||||
Mappings.insert(FOSSIL_SETTING_CRNL_GLOB, Setting("", Setting::TYPE_FOSSIL_LOCAL));
|
||||
|
||||
// Go into portable mode when explicitly requested or if a config file exists next to the executable
|
||||
QString ini_path = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + QDir::separator() + QCoreApplication::applicationName() + ".ini");
|
||||
if( portableMode || QFile::exists(ini_path))
|
||||
store = new QSettings(ini_path, QSettings::IniFormat);
|
||||
else
|
||||
{
|
||||
// Linux: ~/.config/organizationName/applicationName.conf
|
||||
// Windows: HKEY_CURRENT_USER\Software\organizationName\Fuel
|
||||
store = new QSettings(QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
}
|
||||
Q_ASSERT(store);
|
||||
|
||||
if(!HasValue(FUEL_SETTING_FILE_DBLCLICK))
|
||||
SetValue(FUEL_SETTING_FILE_DBLCLICK, 0);
|
||||
if(!HasValue(FUEL_SETTING_LANGUAGE) && SupportsLang(QLocale::system().name()))
|
||||
SetValue(FUEL_SETTING_LANGUAGE, QLocale::system().name());
|
||||
if(!HasValue(FUEL_SETTING_WEB_BROWSER))
|
||||
SetValue(FUEL_SETTING_WEB_BROWSER, 0);
|
||||
|
||||
|
||||
for(int i=0; i<MAX_CUSTOM_ACTIONS; ++i)
|
||||
{
|
||||
CustomAction action;
|
||||
action.Id = QObject::tr("Custom Action %0").arg(i+1);
|
||||
customActions.append(action);
|
||||
}
|
||||
|
||||
ApplyEnvironment();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
Settings::~Settings()
|
||||
{
|
||||
Q_ASSERT(store);
|
||||
delete store;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Settings::ApplyEnvironment()
|
||||
{
|
||||
QString lang_id = GetValue(FUEL_SETTING_LANGUAGE).toString();
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||||
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
|
||||
#endif
|
||||
if(!InstallLang(lang_id))
|
||||
SetValue(FUEL_SETTING_LANGUAGE, "en_US");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Settings::InstallLang(const QString &langId)
|
||||
{
|
||||
if(langId == "en_US")
|
||||
{
|
||||
QCoreApplication::instance()->removeTranslator(&translator);
|
||||
return true;
|
||||
}
|
||||
|
||||
QString locale_path = QString(":intl/intl/%0.qm").arg(langId);
|
||||
if(!translator.load(locale_path))
|
||||
return false;
|
||||
|
||||
Q_ASSERT(!translator.isEmpty());
|
||||
QCoreApplication::instance()->installTranslator(&translator);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Settings::HasValue(const QString &name) const
|
||||
{
|
||||
return store->contains(name);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const QVariant Settings::GetValue(const QString &name)
|
||||
{
|
||||
if(!HasValue(name))
|
||||
return QVariant();
|
||||
return store->value(name);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Settings::SetValue(const QString &name, const QVariant &value)
|
||||
{
|
||||
store->setValue(name, value);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
QVariant &Settings::GetFossilValue(const QString &name)
|
||||
{
|
||||
mappings_t::iterator it=Mappings.find(name);
|
||||
Q_ASSERT(it!=Mappings.end());
|
||||
return it.value().Value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Settings::SetFossilValue(const QString &name, const QVariant &value)
|
||||
{
|
||||
mappings_t::iterator it=Mappings.find(name);
|
||||
Q_ASSERT(it!=Mappings.end());
|
||||
it->Value = value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Settings::SupportsLang(const QString &langId) const
|
||||
{
|
||||
QString locale_path = QString(":intl/intl/%0.qm").arg(langId);
|
||||
QResource res(locale_path);
|
||||
return res.isValid();
|
||||
}
|
126
src/Settings.h
126
src/Settings.h
@ -1,126 +0,0 @@
|
||||
#ifndef SETTINGS_H
|
||||
#define SETTINGS_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
#include <QTranslator>
|
||||
#include <QVector>
|
||||
|
||||
#define FUEL_SETTING_FOSSIL_PATH "FossilPath"
|
||||
#define FUEL_SETTING_COMMIT_MSG "CommitMsgHistory"
|
||||
#define FUEL_SETTING_FILE_DBLCLICK "FileDblClickAction"
|
||||
#define FUEL_SETTING_LANGUAGE "Language"
|
||||
#define FUEL_SETTING_WEB_BROWSER "WebBrowser"
|
||||
|
||||
#define FOSSIL_SETTING_GDIFF_CMD "gdiff-command"
|
||||
#define FOSSIL_SETTING_GMERGE_CMD "gmerge-command"
|
||||
#define FOSSIL_SETTING_PROXY_URL "proxy"
|
||||
#define FOSSIL_SETTING_IGNORE_GLOB "ignore-glob"
|
||||
#define FOSSIL_SETTING_CRNL_GLOB "crnl-glob"
|
||||
#define FOSSIL_SETTING_HTTP_PORT "http-port"
|
||||
|
||||
|
||||
enum FileDblClickAction
|
||||
{
|
||||
FILE_DLBCLICK_ACTION_DIFF,
|
||||
FILE_DLBCLICK_ACTION_OPEN,
|
||||
FILE_DLBCLICK_ACTION_OPENCONTAINING,
|
||||
FILE_DLBCLICK_ACTION_CUSTOM, // Custom Action 1
|
||||
FILE_DLBCLICK_ACTION_MAX
|
||||
};
|
||||
|
||||
|
||||
enum CustomActionContext
|
||||
{
|
||||
ACTION_CONTEXT_FILES = 1 << 0,
|
||||
ACTION_CONTEXT_FOLDERS = 1 << 1,
|
||||
ACTION_CONTEXT_FILES_AND_FOLDERS = ACTION_CONTEXT_FILES|ACTION_CONTEXT_FOLDERS
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_CUSTOM_ACTIONS = 9
|
||||
};
|
||||
|
||||
struct CustomAction
|
||||
{
|
||||
QString Id;
|
||||
QString Description;
|
||||
QString Command;
|
||||
CustomActionContext Context;
|
||||
bool MultipleSelection;
|
||||
|
||||
CustomAction()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return !(Description.isEmpty() || Command.isEmpty());
|
||||
}
|
||||
|
||||
bool IsActive(CustomActionContext context) const
|
||||
{
|
||||
return (Context & context) != 0;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Description.clear();
|
||||
Command.clear();
|
||||
Context = ACTION_CONTEXT_FILES;
|
||||
MultipleSelection = true;
|
||||
}
|
||||
};
|
||||
|
||||
struct Settings
|
||||
{
|
||||
struct Setting
|
||||
{
|
||||
enum SettingType
|
||||
{
|
||||
TYPE_FOSSIL_GLOBAL,
|
||||
TYPE_FOSSIL_LOCAL
|
||||
};
|
||||
|
||||
Setting(QVariant value, SettingType type) : Value(value), Type(type)
|
||||
{}
|
||||
QVariant Value;
|
||||
SettingType Type;
|
||||
};
|
||||
typedef QMap<QString, Setting> mappings_t;
|
||||
typedef QVector<CustomAction> custom_actions_t;
|
||||
|
||||
|
||||
Settings(bool portableMode = false);
|
||||
~Settings();
|
||||
|
||||
void ApplyEnvironment();
|
||||
|
||||
// App configuration access
|
||||
class QSettings * GetStore() { return store; }
|
||||
bool HasValue(const QString &name) const; // store->contains(FUEL_SETTING_FOSSIL_PATH)
|
||||
const QVariant GetValue(const QString &name); // settings.store->value
|
||||
void SetValue(const QString &name, const QVariant &value); // settings.store->value
|
||||
|
||||
// Fossil configuration access
|
||||
QVariant & GetFossilValue(const QString &name);
|
||||
void SetFossilValue(const QString &name, const QVariant &value);
|
||||
mappings_t & GetMappings() { return Mappings; }
|
||||
|
||||
bool SupportsLang(const QString &langId) const;
|
||||
bool InstallLang(const QString &langId);
|
||||
|
||||
custom_actions_t &GetCustomActions() { return customActions; }
|
||||
private:
|
||||
mappings_t Mappings;
|
||||
class QSettings *store;
|
||||
QTranslator translator;
|
||||
|
||||
custom_actions_t customActions;
|
||||
};
|
||||
|
||||
|
||||
#endif // SETTINGS_H
|
@ -1,8 +1,37 @@
|
||||
#include "SettingsDialog.h"
|
||||
#include "ui_SettingsDialog.h"
|
||||
#include <QFileDialog>
|
||||
#include "Utils.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QTranslator>
|
||||
#include <QResource>
|
||||
#include <QTextCodec>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
QString SettingsDialog::SelectExe(QWidget *parent, const QString &description)
|
||||
{
|
||||
QString filter(tr("Applications"));
|
||||
#ifdef Q_OS_WIN
|
||||
filter += " (*.exe)";
|
||||
#else
|
||||
filter += " (*)";
|
||||
#endif
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
parent,
|
||||
description,
|
||||
QString(),
|
||||
filter,
|
||||
&filter);
|
||||
|
||||
if(!QFile::exists(path))
|
||||
return QString();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
SettingsDialog::SettingsDialog(QWidget *parent, Settings &_settings) :
|
||||
@ -17,7 +46,6 @@ SettingsDialog::SettingsDialog(QWidget *parent, Settings &_settings) :
|
||||
ui->cmbDoubleClickAction->addItem(tr("Diff File"));
|
||||
ui->cmbDoubleClickAction->addItem(tr("Open File"));
|
||||
ui->cmbDoubleClickAction->addItem(tr("Open Containing Folder"));
|
||||
ui->cmbDoubleClickAction->addItem(tr("Custom Action %0").arg(1));
|
||||
|
||||
ui->cmbFossilBrowser->addItem(tr("System"));
|
||||
ui->cmbFossilBrowser->addItem(tr("Internal"));
|
||||
@ -26,6 +54,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, Settings &_settings) :
|
||||
ui->lineFossilPath->setText(QDir::toNativeSeparators(settings->GetValue(FUEL_SETTING_FOSSIL_PATH).toString()));
|
||||
ui->cmbDoubleClickAction->setCurrentIndex(settings->GetValue(FUEL_SETTING_FILE_DBLCLICK).toInt());
|
||||
ui->cmbFossilBrowser->setCurrentIndex(settings->GetValue(FUEL_SETTING_WEB_BROWSER).toInt());
|
||||
ui->lineUIPort->setText(settings->GetValue(FUEL_SETTING_HTTP_PORT).toString());
|
||||
|
||||
// Initialize language combo
|
||||
foreach(const LangMap &m, langMap)
|
||||
@ -37,22 +66,15 @@ SettingsDialog::SettingsDialog(QWidget *parent, Settings &_settings) :
|
||||
ui->cmbActiveLanguage->findText(
|
||||
LangIdToName(lang)));
|
||||
|
||||
// Global Settings
|
||||
ui->lineGDiffCommand->setText(settings->GetFossilValue(FOSSIL_SETTING_GDIFF_CMD).toString());
|
||||
ui->lineGMergeCommand->setText(settings->GetFossilValue(FOSSIL_SETTING_GMERGE_CMD).toString());
|
||||
ui->lineProxy->setText(settings->GetFossilValue(FOSSIL_SETTING_PROXY_URL).toString());
|
||||
|
||||
lastActionIndex = 0;
|
||||
currentCustomActions = settings->GetCustomActions();
|
||||
|
||||
ui->cmbCustomActionContext->addItem(tr("Files"));
|
||||
ui->cmbCustomActionContext->addItem(tr("Folders"));
|
||||
ui->cmbCustomActionContext->setCurrentIndex(0);
|
||||
|
||||
GetCustomAction(0);
|
||||
|
||||
for(int i=0; i<currentCustomActions.size(); ++i)
|
||||
{
|
||||
CustomAction &a = currentCustomActions[i];
|
||||
ui->cmbCustomAction->addItem(a.Id);
|
||||
}
|
||||
ui->cmbCustomAction->setCurrentIndex(0);
|
||||
// Repository Settings
|
||||
ui->lineRemoteURL->setText(settings->GetFossilValue(FOSSIL_SETTING_REMOTE_URL).toString());
|
||||
ui->lineIgnore->setText(settings->GetFossilValue(FOSSIL_SETTING_IGNORE_GLOB).toString());
|
||||
ui->lineIgnoreCRNL->setText(settings->GetFossilValue(FOSSIL_SETTING_CRNL_GLOB).toString());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -75,6 +97,7 @@ void SettingsDialog::on_buttonBox_accepted()
|
||||
Q_ASSERT(ui->cmbDoubleClickAction->currentIndex()>=FILE_DLBCLICK_ACTION_DIFF && ui->cmbDoubleClickAction->currentIndex()<FILE_DLBCLICK_ACTION_MAX);
|
||||
settings->SetValue(FUEL_SETTING_FILE_DBLCLICK, ui->cmbDoubleClickAction->currentIndex());
|
||||
settings->SetValue(FUEL_SETTING_WEB_BROWSER, ui->cmbFossilBrowser->currentIndex());
|
||||
settings->SetValue(FUEL_SETTING_HTTP_PORT, ui->lineUIPort->text());
|
||||
|
||||
Q_ASSERT(settings->HasValue(FUEL_SETTING_LANGUAGE));
|
||||
QString curr_langid = settings->GetValue(FUEL_SETTING_LANGUAGE).toString();
|
||||
@ -85,16 +108,14 @@ void SettingsDialog::on_buttonBox_accepted()
|
||||
if(curr_langid != new_langid)
|
||||
QMessageBox::information(this, tr("Restart required"), tr("The language change will take effect after restarting the application"), QMessageBox::Ok);
|
||||
|
||||
for(int i=0; i<currentCustomActions.size(); ++i)
|
||||
{
|
||||
CustomAction &a = currentCustomActions[i];
|
||||
a.Description = a.Description.trimmed();
|
||||
a.Command = a.Command.trimmed();
|
||||
}
|
||||
settings->SetFossilValue(FOSSIL_SETTING_GDIFF_CMD, ui->lineGDiffCommand->text());
|
||||
settings->SetFossilValue(FOSSIL_SETTING_GMERGE_CMD, ui->lineGMergeCommand->text());
|
||||
settings->SetFossilValue(FOSSIL_SETTING_PROXY_URL, ui->lineProxy->text());
|
||||
|
||||
PutCustomAction(ui->cmbCustomAction->currentIndex());
|
||||
settings->SetFossilValue(FOSSIL_SETTING_REMOTE_URL, ui->lineRemoteURL->text());
|
||||
settings->SetFossilValue(FOSSIL_SETTING_IGNORE_GLOB, ui->lineIgnore->text());
|
||||
settings->SetFossilValue(FOSSIL_SETTING_CRNL_GLOB, ui->lineIgnoreCRNL->text());
|
||||
|
||||
settings->GetCustomActions() = currentCustomActions;
|
||||
|
||||
settings->ApplyEnvironment();
|
||||
}
|
||||
@ -107,6 +128,22 @@ void SettingsDialog::on_btnSelectFossil_clicked()
|
||||
ui->lineFossilPath->setText(QDir::toNativeSeparators(path));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SettingsDialog::on_btnSelectFossilGDiff_clicked()
|
||||
{
|
||||
QString path = SelectExe(this, tr("Select Graphical Diff application"));
|
||||
if(!path.isEmpty())
|
||||
ui->lineGDiffCommand->setText(QDir::toNativeSeparators(path));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SettingsDialog::on_btnSelectGMerge_clicked()
|
||||
{
|
||||
QString path = SelectExe(this, tr("Select Graphical Merge application"));
|
||||
if(!path.isEmpty())
|
||||
ui->lineGMergeCommand->setText(path);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SettingsDialog::on_btnClearMessageHistory_clicked()
|
||||
{
|
||||
@ -153,58 +190,119 @@ QString SettingsDialog::LangNameToId(const QString &name)
|
||||
return "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SettingsDialog::on_btnSelectCustomFileActionCommand_clicked()
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
Settings::Settings(bool portableMode) : store(0)
|
||||
{
|
||||
QString path = SelectExe(this, tr("Select command"));
|
||||
if(path.isEmpty())
|
||||
return;
|
||||
Mappings.insert(FOSSIL_SETTING_GDIFF_CMD, Setting("", Setting::TYPE_FOSSIL_GLOBAL));
|
||||
Mappings.insert(FOSSIL_SETTING_GMERGE_CMD, Setting("", Setting::TYPE_FOSSIL_GLOBAL));
|
||||
Mappings.insert(FOSSIL_SETTING_PROXY_URL, Setting("", Setting::TYPE_FOSSIL_GLOBAL));
|
||||
|
||||
// Quote path if it contains spaces
|
||||
if(path.indexOf(' ')!=-1)
|
||||
path = '"' + path + '"';
|
||||
Mappings.insert(FOSSIL_SETTING_IGNORE_GLOB, Setting("", Setting::TYPE_FOSSIL_LOCAL));
|
||||
Mappings.insert(FOSSIL_SETTING_CRNL_GLOB, Setting("", Setting::TYPE_FOSSIL_LOCAL));
|
||||
Mappings.insert(FOSSIL_SETTING_REMOTE_URL, Setting("off", Setting::TYPE_FOSSIL_COMMAND));
|
||||
|
||||
ui->lineCustomActionCommand->setText(QDir::toNativeSeparators(path));
|
||||
// Go into portable mode when explicitly requested or if a config file exists next to the executable
|
||||
QString ini_path = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + QDir::separator() + QCoreApplication::applicationName() + ".ini");
|
||||
if( portableMode || QFile::exists(ini_path))
|
||||
store = new QSettings(ini_path, QSettings::IniFormat);
|
||||
else
|
||||
{
|
||||
// Linux: ~/.config/organizationName/applicationName.conf
|
||||
// Windows: HKEY_CURRENT_USER\Software\organizationName\Fuel
|
||||
store = new QSettings(QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());
|
||||
}
|
||||
Q_ASSERT(store);
|
||||
|
||||
if(!HasValue(FUEL_SETTING_FILE_DBLCLICK))
|
||||
SetValue(FUEL_SETTING_FILE_DBLCLICK, 0);
|
||||
if(!HasValue(FUEL_SETTING_LANGUAGE) && SupportsLang(QLocale::system().name()))
|
||||
SetValue(FUEL_SETTING_LANGUAGE, QLocale::system().name());
|
||||
if(!HasValue(FUEL_SETTING_WEB_BROWSER))
|
||||
SetValue(FUEL_SETTING_WEB_BROWSER, 0);
|
||||
if(!HasValue(FUEL_SETTING_HTTP_PORT))
|
||||
SetValue(FUEL_SETTING_HTTP_PORT, "8090");
|
||||
|
||||
ApplyEnvironment();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SettingsDialog::GetCustomAction(int index)
|
||||
Settings::~Settings()
|
||||
{
|
||||
Q_ASSERT(index>=0 && index < currentCustomActions.size());
|
||||
CustomAction &action = currentCustomActions[index];
|
||||
ui->lineCustomActionDescription->setText(action.Description);
|
||||
ui->lineCustomActionCommand->setText(action.Command);
|
||||
ui->cmbCustomActionContext->setCurrentIndex(action.Context-1);
|
||||
ui->chkCustomActionMultipleSelection->setChecked(action.MultipleSelection);
|
||||
Q_ASSERT(store);
|
||||
delete store;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SettingsDialog::PutCustomAction(int index)
|
||||
void Settings::ApplyEnvironment()
|
||||
{
|
||||
Q_ASSERT(index>=0 && index < currentCustomActions.size());
|
||||
CustomAction &action = currentCustomActions[index];
|
||||
action.Description = ui->lineCustomActionDescription->text().trimmed();
|
||||
action.Command = ui->lineCustomActionCommand->text().trimmed();
|
||||
action.Context = static_cast<CustomActionContext>(ui->cmbCustomActionContext->currentIndex()+1);
|
||||
action.MultipleSelection = ui->chkCustomActionMultipleSelection->isChecked();
|
||||
QString lang_id = GetValue(FUEL_SETTING_LANGUAGE).toString();
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||||
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
|
||||
#endif
|
||||
if(!InstallLang(lang_id))
|
||||
SetValue(FUEL_SETTING_LANGUAGE, "en_US");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SettingsDialog::on_cmbCustomAction_currentIndexChanged(int index)
|
||||
bool Settings::InstallLang(const QString &langId)
|
||||
{
|
||||
if(index != lastActionIndex)
|
||||
PutCustomAction(lastActionIndex);
|
||||
if(langId == "en_US")
|
||||
{
|
||||
QCoreApplication::instance()->removeTranslator(&translator);
|
||||
return true;
|
||||
}
|
||||
|
||||
GetCustomAction(index);
|
||||
lastActionIndex = index;
|
||||
QString locale_path = QString(":intl/intl/%0.qm").arg(langId);
|
||||
if(!translator.load(locale_path))
|
||||
return false;
|
||||
|
||||
Q_ASSERT(!translator.isEmpty());
|
||||
QCoreApplication::instance()->installTranslator(&translator);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SettingsDialog::on_cmbCustomActionContext_currentIndexChanged(int index)
|
||||
bool Settings::HasValue(const QString &name) const
|
||||
{
|
||||
int action_index = ui->cmbCustomAction->currentIndex();
|
||||
if(action_index<0)
|
||||
return;
|
||||
Q_ASSERT(action_index>=0 && action_index < currentCustomActions.size());
|
||||
currentCustomActions[action_index].Context = static_cast<CustomActionContext>(index+1);
|
||||
return store->contains(name);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const QVariant Settings::GetValue(const QString &name)
|
||||
{
|
||||
if(!HasValue(name))
|
||||
return QVariant();
|
||||
return store->value(name);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Settings::SetValue(const QString &name, const QVariant &value)
|
||||
{
|
||||
store->setValue(name, value);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
QVariant &Settings::GetFossilValue(const QString &name)
|
||||
{
|
||||
mappings_t::iterator it=Mappings.find(name);
|
||||
Q_ASSERT(it!=Mappings.end());
|
||||
return it.value().Value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Settings::SetFossilValue(const QString &name, const QVariant &value)
|
||||
{
|
||||
mappings_t::iterator it=Mappings.find(name);
|
||||
Q_ASSERT(it!=Mappings.end());
|
||||
it->Value = value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Settings::SupportsLang(const QString &langId) const
|
||||
{
|
||||
QString locale_path = QString(":intl/intl/%0.qm").arg(langId);
|
||||
QResource res(locale_path);
|
||||
return res.isValid();
|
||||
}
|
||||
|
@ -2,12 +2,82 @@
|
||||
#define SETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "Settings.h"
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
#include <QTranslator>
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class SettingsDialog;
|
||||
}
|
||||
|
||||
#define FUEL_SETTING_FOSSIL_PATH "FossilPath"
|
||||
#define FUEL_SETTING_COMMIT_MSG "CommitMsgHistory"
|
||||
#define FUEL_SETTING_FILE_DBLCLICK "FileDblClickAction"
|
||||
#define FUEL_SETTING_LANGUAGE "Language"
|
||||
#define FUEL_SETTING_WEB_BROWSER "WebBrowser"
|
||||
#define FUEL_SETTING_HTTP_PORT "HTTPPort"
|
||||
|
||||
#define FOSSIL_SETTING_GDIFF_CMD "gdiff-command"
|
||||
#define FOSSIL_SETTING_GMERGE_CMD "gmerge-command"
|
||||
#define FOSSIL_SETTING_PROXY_URL "proxy"
|
||||
#define FOSSIL_SETTING_IGNORE_GLOB "ignore-glob"
|
||||
#define FOSSIL_SETTING_CRNL_GLOB "crnl-glob"
|
||||
#define FOSSIL_SETTING_REMOTE_URL "remote-url"
|
||||
|
||||
|
||||
enum FileDblClickAction
|
||||
{
|
||||
FILE_DLBCLICK_ACTION_DIFF,
|
||||
FILE_DLBCLICK_ACTION_OPEN,
|
||||
FILE_DLBCLICK_ACTION_OPENCONTAINING,
|
||||
FILE_DLBCLICK_ACTION_MAX
|
||||
};
|
||||
|
||||
struct Settings
|
||||
{
|
||||
struct Setting
|
||||
{
|
||||
enum SettingType
|
||||
{
|
||||
TYPE_FOSSIL_GLOBAL,
|
||||
TYPE_FOSSIL_LOCAL,
|
||||
TYPE_FOSSIL_COMMAND
|
||||
};
|
||||
|
||||
Setting(QVariant value, SettingType type) : Value(value), Type(type)
|
||||
{}
|
||||
QVariant Value;
|
||||
SettingType Type;
|
||||
};
|
||||
typedef QMap<QString, Setting> mappings_t;
|
||||
|
||||
|
||||
Settings(bool portableMode = false);
|
||||
~Settings();
|
||||
|
||||
void ApplyEnvironment();
|
||||
|
||||
// App configuration access
|
||||
class QSettings * GetStore() { return store; }
|
||||
bool HasValue(const QString &name) const; // store->contains(FUEL_SETTING_FOSSIL_PATH)
|
||||
const QVariant GetValue(const QString &name); // settings.store->value
|
||||
void SetValue(const QString &name, const QVariant &value); // settings.store->value
|
||||
|
||||
// Fossil configuration access
|
||||
QVariant & GetFossilValue(const QString &name);
|
||||
void SetFossilValue(const QString &name, const QVariant &value);
|
||||
mappings_t & GetMappings() { return Mappings; }
|
||||
|
||||
bool SupportsLang(const QString &langId) const;
|
||||
bool InstallLang(const QString &langId);
|
||||
private:
|
||||
mappings_t Mappings;
|
||||
class QSettings *store;
|
||||
QTranslator translator;
|
||||
};
|
||||
|
||||
|
||||
class SettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -22,17 +92,15 @@ public:
|
||||
private slots:
|
||||
void on_btnSelectFossil_clicked();
|
||||
void on_buttonBox_accepted();
|
||||
void on_btnSelectFossilGDiff_clicked();
|
||||
void on_btnSelectGMerge_clicked();
|
||||
void on_btnClearMessageHistory_clicked();
|
||||
void on_btnSelectCustomFileActionCommand_clicked();
|
||||
void on_cmbCustomAction_currentIndexChanged(int index);
|
||||
void on_cmbCustomActionContext_currentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
static QString SelectExe(QWidget *parent, const QString &description);
|
||||
QString LangIdToName(const QString &id);
|
||||
QString LangNameToId(const QString &name);
|
||||
void CreateLangMap();
|
||||
void GetCustomAction(int index);
|
||||
void PutCustomAction(int index);
|
||||
|
||||
struct LangMap
|
||||
{
|
||||
@ -48,8 +116,6 @@ private:
|
||||
QList<LangMap> langMap;
|
||||
Ui::SettingsDialog *ui;
|
||||
Settings *settings;
|
||||
Settings::custom_actions_t currentCustomActions;
|
||||
int lastActionIndex;
|
||||
};
|
||||
|
||||
#endif // SETTINGSDIALOG_H
|
||||
|
352
src/Utils.cpp
352
src/Utils.cpp
@ -1,12 +1,6 @@
|
||||
#include "Utils.h"
|
||||
#include <QMessageBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFileDialog>
|
||||
#include <QEventLoop>
|
||||
#include <QUrl>
|
||||
#include <QProcess>
|
||||
#include <QCryptographicHash>
|
||||
#include "ext/qtkeychain/keychain.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
QMessageBox::StandardButton DialogQuery(QWidget *parent, const QString &title, const QString &query, QMessageBox::StandardButtons buttons)
|
||||
@ -20,54 +14,6 @@ QMessageBox::StandardButton DialogQuery(QWidget *parent, const QString &title, c
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
QString QuotePath(const QString &path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
QStringList QuotePaths(const QStringList &paths)
|
||||
{
|
||||
QStringList res;
|
||||
for(int i=0; i<paths.size(); ++i)
|
||||
res.append(QuotePath(paths[i]));
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
QString SelectExe(QWidget *parent, const QString &description)
|
||||
{
|
||||
QString filter(QObject::tr("Applications"));
|
||||
#ifdef Q_OS_WIN
|
||||
filter += " (*.exe)";
|
||||
#else
|
||||
filter += " (*)";
|
||||
#endif
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
parent,
|
||||
description,
|
||||
QString(),
|
||||
filter,
|
||||
&filter);
|
||||
|
||||
if(!QFile::exists(path))
|
||||
return QString();
|
||||
|
||||
#ifdef Q_OS_MACX
|
||||
// Guess actual executable from bundle dir
|
||||
QFileInfo fi(path);
|
||||
if(fi.isDir() && path.indexOf(".app")!=-1)
|
||||
{
|
||||
path += "/Contents/MacOS/" + fi.baseName();
|
||||
|
||||
if(!QFile::exists(path))
|
||||
return QString();
|
||||
}
|
||||
#endif
|
||||
|
||||
return path;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
#if 0 // Unused
|
||||
#include <QInputDialog>
|
||||
@ -345,301 +291,3 @@ bool ShowExplorerMenu(HWND hwnd, const QString &path, const QPoint &qpoint)
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ParseProperties(QStringMap &properties, const QStringList &lines, QChar separator)
|
||||
{
|
||||
properties.clear();
|
||||
foreach(QString l, lines)
|
||||
{
|
||||
l = l.trimmed();
|
||||
int index = l.indexOf(separator);
|
||||
|
||||
QString key;
|
||||
QString value;
|
||||
if(index!=-1)
|
||||
{
|
||||
key = l.left(index).trimmed();
|
||||
value = l.mid(index+1).trimmed();
|
||||
}
|
||||
else
|
||||
key = l;
|
||||
|
||||
properties.insert(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void GetStandardItemTextRecursive(QString &name, const QStandardItem &item, const QChar &separator)
|
||||
{
|
||||
if(item.parent())
|
||||
{
|
||||
GetStandardItemTextRecursive(name, *item.parent());
|
||||
name.append(separator);
|
||||
}
|
||||
|
||||
name.append(item.data(Qt::DisplayRole).toString());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void BuildNameToModelIndex(name_modelindex_map_t &map, const QStandardItem &item)
|
||||
{
|
||||
QString name;
|
||||
GetStandardItemTextRecursive(name, item);
|
||||
map.insert(name, item.index());
|
||||
|
||||
for(int i=0; i<item.rowCount(); ++i)
|
||||
{
|
||||
const QStandardItem *child = item.child(i);
|
||||
Q_ASSERT(child);
|
||||
BuildNameToModelIndex(map, *child);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void BuildNameToModelIndex(name_modelindex_map_t &map, const QStandardItemModel &model)
|
||||
{
|
||||
for(int i=0; i<model.rowCount(); ++i)
|
||||
{
|
||||
const QStandardItem *item = model.item(i);
|
||||
Q_ASSERT(item);
|
||||
BuildNameToModelIndex(map, *item);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool KeychainSet(QObject *parent, const QUrl &url, QSettings &settings)
|
||||
{
|
||||
QEventLoop loop(parent);
|
||||
QKeychain::WritePasswordJob job(UrlToStringNoCredentials(url));
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
settings.beginGroup("Keychain");
|
||||
job.setSettings(&settings);
|
||||
#else
|
||||
Q_UNUSED(settings)
|
||||
#endif
|
||||
|
||||
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) );
|
||||
job.setAutoDelete( false );
|
||||
job.setInsecureFallback(false);
|
||||
job.setKey(url.userName());
|
||||
job.setTextData(url.password());
|
||||
job.start();
|
||||
loop.exec();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
settings.endGroup();
|
||||
#endif
|
||||
|
||||
return job.error() == QKeychain::NoError;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool KeychainGet(QObject *parent, QUrl &url, QSettings &settings)
|
||||
{
|
||||
QEventLoop loop(parent);
|
||||
QKeychain::ReadPasswordJob job(UrlToStringNoCredentials(url));
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
settings.beginGroup("Keychain");
|
||||
job.setSettings(&settings);
|
||||
#else
|
||||
Q_UNUSED(settings)
|
||||
#endif
|
||||
|
||||
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()));
|
||||
job.setAutoDelete( false );
|
||||
job.setInsecureFallback(false);
|
||||
job.setAutoDelete( false );
|
||||
job.setKey(url.userName());
|
||||
job.start();
|
||||
loop.exec();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
settings.endGroup();
|
||||
#endif
|
||||
|
||||
if(job.error() != QKeychain::NoError)
|
||||
return false;
|
||||
|
||||
url.setUserName(job.key());
|
||||
url.setPassword(job.textData());
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool KeychainDelete(QObject* parent, const QUrl& url, QSettings &settings)
|
||||
{
|
||||
QEventLoop loop(parent);
|
||||
QKeychain::DeletePasswordJob job(UrlToStringNoCredentials(url));
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
settings.beginGroup("Keychain");
|
||||
job.setSettings(&settings);
|
||||
#else
|
||||
Q_UNUSED(settings)
|
||||
#endif
|
||||
|
||||
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()));
|
||||
job.setAutoDelete( false );
|
||||
job.setInsecureFallback(false);
|
||||
job.setAutoDelete( false );
|
||||
job.setKey(url.userName());
|
||||
job.start();
|
||||
loop.exec();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
settings.endGroup();
|
||||
#endif
|
||||
|
||||
return job.error() == QKeychain::NoError;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString HashString(const QString& str)
|
||||
{
|
||||
QCryptographicHash hash(QCryptographicHash::Sha1);
|
||||
const QByteArray ba(str.toUtf8());
|
||||
hash.addData(ba.data(), ba.size());
|
||||
QString str_out(hash.result().toHex());
|
||||
return str_out;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString UrlToStringDisplay(const QUrl& url)
|
||||
{
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||||
return url.toString(QUrl::RemovePassword);
|
||||
#else
|
||||
return url.toDisplayString();
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString UrlToStringNoCredentials(const QUrl& url)
|
||||
{
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
|
||||
return url.toString(QUrl::RemoveUserInfo);
|
||||
#else
|
||||
return url.toString(QUrl::PrettyDecoded|QUrl::RemoveUserInfo);
|
||||
#endif
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void SplitCommandLine(const QString &commandLine, QString &command, QString &extraParams)
|
||||
{
|
||||
// Process command string
|
||||
command = commandLine.trimmed();
|
||||
|
||||
Q_ASSERT(!command.isEmpty());
|
||||
|
||||
// Split command from embedded params
|
||||
extraParams.clear();
|
||||
|
||||
// Command ends after first space
|
||||
QChar cmd_char_end = ' ';
|
||||
int cmd_start = 0;
|
||||
int backtrack = 0;
|
||||
|
||||
// ...unless it is a quoted command
|
||||
if(command[0]=='"')
|
||||
{
|
||||
cmd_char_end = '"';
|
||||
cmd_start = 1;
|
||||
backtrack = 1;
|
||||
}
|
||||
|
||||
int cmd_end = command.indexOf(cmd_char_end, cmd_start);
|
||||
if(cmd_end > 0)
|
||||
{
|
||||
extraParams = command.mid(cmd_end+1);
|
||||
command = command.mid(cmd_start, cmd_end-backtrack);
|
||||
}
|
||||
|
||||
command = command.trimmed();
|
||||
extraParams = extraParams.trimmed();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool SpawnExternalProcess(QObject *processParent, const QString& command, const QStringList& fileList, const stringset_t& pathSet, const QString &workspaceDir, UICallback &uiCallback)
|
||||
{
|
||||
static const char* MACRO_FILE = "%FILE";
|
||||
static const char* MACRO_FOLDER = "%FOLDER";
|
||||
static const char* MACRO_WORKSPACE = "%WORKSPACE";
|
||||
|
||||
QStringList params;
|
||||
|
||||
QString cmd, extra_params;
|
||||
SplitCommandLine(command, cmd, extra_params);
|
||||
|
||||
// Push all additional params, except those containing macros
|
||||
QString macro_file;
|
||||
QString macro_folder;
|
||||
|
||||
if(!extra_params.isEmpty())
|
||||
{
|
||||
QStringList extra_param_list = extra_params.split(' ');
|
||||
|
||||
foreach(const QString &p, extra_param_list)
|
||||
{
|
||||
if(p.indexOf(MACRO_FILE)!=-1)
|
||||
{
|
||||
macro_file = p;
|
||||
continue;
|
||||
}
|
||||
else if(p.indexOf(MACRO_FOLDER)!=-1)
|
||||
{
|
||||
macro_folder = p;
|
||||
continue;
|
||||
}
|
||||
else if(p.indexOf(MACRO_WORKSPACE)!=-1)
|
||||
{
|
||||
// Add in-place
|
||||
QString n = p;
|
||||
n.replace(MACRO_WORKSPACE, QDir::toNativeSeparators(workspaceDir), Qt::CaseInsensitive);
|
||||
params.push_back(n);
|
||||
continue;
|
||||
}
|
||||
|
||||
params.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
// Build file params
|
||||
if(!macro_file.isEmpty())
|
||||
{
|
||||
foreach(const QString &f, fileList)
|
||||
{
|
||||
QString path = QDir::toNativeSeparators(QFileInfo(workspaceDir + PATH_SEPARATOR + f).absoluteFilePath());
|
||||
|
||||
QString macro = macro_file;
|
||||
path = macro.replace(MACRO_FILE, path, Qt::CaseInsensitive);
|
||||
params.append(path);
|
||||
}
|
||||
}
|
||||
|
||||
// Build folder params
|
||||
if(!macro_folder.isEmpty())
|
||||
{
|
||||
foreach(const QString &f, pathSet)
|
||||
{
|
||||
QString path = QDir::toNativeSeparators(QFileInfo(workspaceDir + PATH_SEPARATOR + f).absoluteFilePath());
|
||||
|
||||
QString macro = macro_folder;
|
||||
path = macro.replace(MACRO_FOLDER, path, Qt::CaseInsensitive);
|
||||
params.append(path);
|
||||
}
|
||||
}
|
||||
|
||||
uiCallback.logText("<b>"+cmd + " "+params.join(" ")+"</b><br>", true);
|
||||
|
||||
QProcess proc(processParent);
|
||||
return proc.startDetached(cmd, params);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void TrimStringList(QStringList& list)
|
||||
{
|
||||
for(int i=0; i<list.length(); ++i)
|
||||
list[i] = list[i].trimmed();
|
||||
}
|
||||
|
64
src/Utils.h
64
src/Utils.h
@ -3,74 +3,12 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QMessageBox>
|
||||
#include <QMap>
|
||||
#include <QStandardItem>
|
||||
#include <QSet>
|
||||
#include <QSettings>
|
||||
|
||||
#define COUNTOF(array) (sizeof(array)/sizeof(array[0]))
|
||||
#define FOSSIL_CHECKOUT1 "_FOSSIL_"
|
||||
#define FOSSIL_CHECKOUT2 ".fslckout"
|
||||
#define FOSSIL_EXT "fossil"
|
||||
#define PATH_SEPARATOR "/"
|
||||
|
||||
typedef QSet<QString> stringset_t;
|
||||
|
||||
|
||||
class UICallback
|
||||
{
|
||||
public:
|
||||
virtual void logText(const QString &text, bool isHTML)=0;
|
||||
virtual void beginProcess(const QString &text)=0;
|
||||
virtual void updateProcess(const QString &text)=0;
|
||||
virtual void endProcess()=0;
|
||||
virtual QMessageBox::StandardButton Query(const QString &title, const QString &query, QMessageBox::StandardButtons buttons)=0;
|
||||
};
|
||||
|
||||
|
||||
class ScopedStatus
|
||||
{
|
||||
public:
|
||||
ScopedStatus(UICallback *callback, const QString &text) : uiCallback(callback)
|
||||
{
|
||||
uiCallback->beginProcess(text);
|
||||
}
|
||||
|
||||
~ScopedStatus()
|
||||
{
|
||||
uiCallback->endProcess();
|
||||
}
|
||||
|
||||
private:
|
||||
UICallback *uiCallback;
|
||||
};
|
||||
|
||||
|
||||
QMessageBox::StandardButton DialogQuery(QWidget *parent, const QString &title, const QString &query, QMessageBox::StandardButtons buttons = QMessageBox::Yes|QMessageBox::No);
|
||||
QString QuotePath(const QString &path);
|
||||
QStringList QuotePaths(const QStringList &paths);
|
||||
QString SelectExe(QWidget *parent, const QString &description);
|
||||
|
||||
|
||||
typedef QMap<QString, QModelIndex> name_modelindex_map_t;
|
||||
void GetStandardItemTextRecursive(QString &name, const QStandardItem &item, const QChar &separator='/');
|
||||
void BuildNameToModelIndex(name_modelindex_map_t &map, const QStandardItem &item);
|
||||
void BuildNameToModelIndex(name_modelindex_map_t &map, const QStandardItemModel &model);
|
||||
bool KeychainSet(QObject* parent, const QUrl& url, QSettings &settings);
|
||||
bool KeychainGet(QObject* parent, QUrl& url, QSettings &settings);
|
||||
bool KeychainDelete(QObject* parent, const QUrl& url, QSettings &settings);
|
||||
QString HashString(const QString &str);
|
||||
QString UrlToStringDisplay(const QUrl &url);
|
||||
QString UrlToStringNoCredentials(const QUrl& url);
|
||||
void SplitCommandLine(const QString &commandLine, QString &command, QString &extraParams);
|
||||
bool SpawnExternalProcess(QObject *processParent, const QString& command, const QStringList& fileList, const stringset_t& pathSet, const QString &workspaceDir, UICallback &uiCallback);
|
||||
void TrimStringList(QStringList &list);
|
||||
|
||||
typedef QMap<QString, QString> QStringMap;
|
||||
void ParseProperties(QStringMap &properties, const QStringList &lines, QChar separator=' ');
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
bool ShowExplorerMenu(HWND hwnd, const QString &path, const QPoint &qpoint);
|
||||
#endif
|
||||
|
||||
|
||||
#endif // UTILS_H
|
||||
|
@ -1,426 +0,0 @@
|
||||
#include "Workspace.h"
|
||||
#include <QCoreApplication>
|
||||
#include "Utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
Workspace::Workspace()
|
||||
{
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
Workspace::~Workspace()
|
||||
{
|
||||
clearState();
|
||||
remotes.clear();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Workspace::clearState()
|
||||
{
|
||||
// Dispose RepoFiles
|
||||
foreach(WorkspaceFile *r, getFiles())
|
||||
delete r;
|
||||
|
||||
getFiles().clear();
|
||||
getPaths().clear();
|
||||
pathState.clear();
|
||||
stashMap.clear();
|
||||
branchList.clear();
|
||||
tags.clear();
|
||||
isIntegrated = false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Workspace::storeWorkspace(QSettings &store)
|
||||
{
|
||||
QString workspace = fossil().getWorkspacePath();
|
||||
if(workspace.isEmpty())
|
||||
return;
|
||||
|
||||
store.beginGroup("Remotes");
|
||||
QString workspace_hash = HashString(QDir::toNativeSeparators(workspace));
|
||||
|
||||
store.beginWriteArray(workspace_hash);
|
||||
int index = 0;
|
||||
for(remote_map_t::iterator it=remotes.begin(); it!=remotes.end(); ++it, ++index)
|
||||
{
|
||||
store.setArrayIndex(index);
|
||||
store.setValue("Name", it->name);
|
||||
QUrl url = it->url;
|
||||
url.setPassword("");
|
||||
store.setValue("Url", url);
|
||||
if(it->isDefault)
|
||||
store.setValue("Default", it->isDefault);
|
||||
else
|
||||
store.remove("Default");
|
||||
}
|
||||
store.endArray();
|
||||
store.endGroup();
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Workspace::switchWorkspace(const QString& workspace, QSettings &store)
|
||||
{
|
||||
// Save Remotes
|
||||
storeWorkspace(store);
|
||||
clearState();
|
||||
remotes.clear();
|
||||
|
||||
fossil().setWorkspacePath("");
|
||||
if(workspace.isEmpty())
|
||||
return true;
|
||||
|
||||
QString new_workspace = QFileInfo(workspace).absoluteFilePath();
|
||||
|
||||
if(!QDir::setCurrent(new_workspace))
|
||||
return false;
|
||||
|
||||
fossil().setWorkspacePath(new_workspace);
|
||||
|
||||
// Load Remotes
|
||||
QString workspace_hash = HashString(QDir::toNativeSeparators(new_workspace));
|
||||
|
||||
QString gr = store.group();
|
||||
|
||||
store.beginGroup("Remotes");
|
||||
gr = store.group();
|
||||
int num_remotes = store.beginReadArray(workspace_hash);
|
||||
for(int i=0; i<num_remotes; ++i)
|
||||
{
|
||||
store.setArrayIndex(i);
|
||||
|
||||
QString name = store.value("Name").toString();
|
||||
QUrl url = store.value("Url").toUrl();
|
||||
bool def = store.value("Default", false).toBool();
|
||||
addRemote(url, name);
|
||||
if(def)
|
||||
setRemoteDefault(url);
|
||||
}
|
||||
store.endArray();
|
||||
store.endGroup();
|
||||
|
||||
#if 0 // FIXME: Disabled this because if fossil's remote does not match exactly what we have stored (url and username), it will be automatically added every-time
|
||||
// Add the default url from fossil
|
||||
QUrl default_remote;
|
||||
if(fossil().getRemoteUrl(default_remote) && default_remote.isValid() && !default_remote.isEmpty())
|
||||
{
|
||||
default_remote.setPassword("");
|
||||
|
||||
// Add Default remote if not available already
|
||||
if(findRemote(default_remote)==NULL)
|
||||
{
|
||||
addRemote(default_remote, UrlToStringDisplay(default_remote));
|
||||
if(getRemoteDefault().isEmpty())
|
||||
setRemoteDefault(default_remote);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Workspace::scanDirectory(QFileInfoList &entries, const QString& dirPath, const QString &baseDir, const QStringList &ignorePatterns, const bool &abort, UICallback &uiCallback)
|
||||
{
|
||||
QDir dir(dirPath);
|
||||
|
||||
uiCallback.updateProcess(dirPath);
|
||||
|
||||
QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot);
|
||||
for (int i=0; i<list.count(); ++i)
|
||||
{
|
||||
if(abort)
|
||||
return false;
|
||||
|
||||
QFileInfo info = list[i];
|
||||
QString filepath = info.filePath();
|
||||
QString rel_path = filepath;
|
||||
rel_path.remove(baseDir+PATH_SEPARATOR);
|
||||
|
||||
// Skip ignored files
|
||||
if(!ignorePatterns.isEmpty() && QDir::match(ignorePatterns, rel_path))
|
||||
continue;
|
||||
|
||||
if (info.isDir())
|
||||
{
|
||||
if(!scanDirectory(entries, filepath, baseDir, ignorePatterns, abort, uiCallback))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
entries.push_back(info);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static bool StringLengthDescending(const QString &l, const QString &r)
|
||||
{
|
||||
return l.length() > r.length();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Workspace::scanWorkspace(bool scanLocal, bool scanIgnored, bool scanModified, bool scanUnchanged, const QStringList &ignorePatterns, UICallback &uiCallback, bool &operationAborted)
|
||||
{
|
||||
// Scan all workspace files
|
||||
QFileInfoList all_files;
|
||||
QString wkdir = fossil().getWorkspacePath();
|
||||
|
||||
if(wkdir.isEmpty())
|
||||
return;
|
||||
|
||||
// Retrieve the status of files tracked by fossil
|
||||
QStringList res;
|
||||
if(!fossil().listFiles(res))
|
||||
return;
|
||||
|
||||
bool scan_files = scanLocal;
|
||||
|
||||
clearState();
|
||||
|
||||
QStringList paths;
|
||||
|
||||
operationAborted = false;
|
||||
|
||||
uiCallback.beginProcess("");
|
||||
if(scan_files)
|
||||
{
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
QStringList ignore;
|
||||
if(!scanIgnored)
|
||||
ignore = ignorePatterns;
|
||||
|
||||
if(!scanDirectory(all_files, wkdir, wkdir, ignore, operationAborted, uiCallback))
|
||||
goto _done;
|
||||
|
||||
for(QFileInfoList::iterator it=all_files.begin(); it!=all_files.end(); ++it)
|
||||
{
|
||||
QString filename = it->fileName();
|
||||
QString fullpath = it->absoluteFilePath();
|
||||
|
||||
// Skip fossil files
|
||||
if(filename == FOSSIL_CHECKOUT1 || filename == FOSSIL_CHECKOUT2 || (!fossil().getRepositoryFile().isEmpty() && QFileInfo(fullpath) == QFileInfo(fossil().getRepositoryFile())))
|
||||
continue;
|
||||
|
||||
WorkspaceFile::Type type = WorkspaceFile::TYPE_UNKNOWN;
|
||||
|
||||
WorkspaceFile *rf = new WorkspaceFile(*it, type, wkdir);
|
||||
const QString &path = rf->getPath();
|
||||
getFiles().insert(rf->getFilePath(), rf);
|
||||
getPaths().insert(path);
|
||||
|
||||
// Add or merge file state into directory state
|
||||
pathstate_map_t::iterator state_it = pathState.find(path);
|
||||
if(state_it != pathState.end())
|
||||
state_it.value() = static_cast<WorkspaceFile::Type>(state_it.value() | type);
|
||||
else
|
||||
{
|
||||
pathState.insert(path, type);
|
||||
paths.append(path); // keep path in list for depth sort
|
||||
}
|
||||
}
|
||||
}
|
||||
uiCallback.endProcess();
|
||||
|
||||
uiCallback.beginProcess(QObject::tr("Updating..."));
|
||||
|
||||
// Update Files and Directories
|
||||
for(QStringList::iterator line_it=res.begin(); line_it!=res.end(); ++line_it)
|
||||
{
|
||||
QString line = (*line_it).trimmed();
|
||||
if(line.length()==0)
|
||||
continue;
|
||||
|
||||
int space_index = line.indexOf(' ');
|
||||
if(space_index==-1)
|
||||
continue;
|
||||
|
||||
QString status_text = line.left(space_index);
|
||||
QString fname = line.right(line.length() - space_index).trimmed();
|
||||
WorkspaceFile::Type type = WorkspaceFile::TYPE_UNKNOWN;
|
||||
|
||||
// Generate a RepoFile for all non-existant fossil files
|
||||
// or for all files if we skipped scanning the workspace
|
||||
bool add_missing = !scan_files;
|
||||
|
||||
if(status_text=="EDITED")
|
||||
type = WorkspaceFile::TYPE_EDITTED;
|
||||
else if(status_text=="ADDED")
|
||||
type = WorkspaceFile::TYPE_ADDED;
|
||||
else if(status_text=="DELETED")
|
||||
{
|
||||
type = WorkspaceFile::TYPE_DELETED;
|
||||
add_missing = true;
|
||||
}
|
||||
else if(status_text=="MISSING")
|
||||
{
|
||||
type = WorkspaceFile::TYPE_MISSING;
|
||||
add_missing = true;
|
||||
}
|
||||
else if(status_text=="RENAMED")
|
||||
type = WorkspaceFile::TYPE_RENAMED;
|
||||
else if(status_text=="UNCHANGED")
|
||||
type = WorkspaceFile::TYPE_UNCHANGED;
|
||||
else if(status_text=="CONFLICT")
|
||||
type = WorkspaceFile::TYPE_CONFLICTED;
|
||||
else if(status_text=="UPDATED_BY_MERGE" || status_text=="ADDED_BY_MERGE" || status_text=="ADDED_BY_INTEGRATE" || status_text=="UPDATED_BY_INTEGRATE")
|
||||
type = WorkspaceFile::TYPE_MERGED;
|
||||
|
||||
// Filter unwanted file types
|
||||
if( ((type & WorkspaceFile::TYPE_MODIFIED) && !scanModified) ||
|
||||
((type & WorkspaceFile::TYPE_UNCHANGED) && !scanUnchanged))
|
||||
{
|
||||
getFiles().remove(fname);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
add_missing = true;
|
||||
|
||||
Workspace::filemap_t::iterator it = getFiles().find(fname);
|
||||
|
||||
WorkspaceFile *rf = 0;
|
||||
if(add_missing && it==getFiles().end())
|
||||
{
|
||||
QFileInfo info(wkdir+QDir::separator()+fname);
|
||||
rf = new WorkspaceFile(info, type, wkdir);
|
||||
getFiles().insert(rf->getFilePath(), rf);
|
||||
}
|
||||
|
||||
if(!rf)
|
||||
{
|
||||
it = getFiles().find(fname);
|
||||
Q_ASSERT(it!=getFiles().end());
|
||||
rf = *it;
|
||||
}
|
||||
|
||||
rf->setType(type);
|
||||
|
||||
QString path = rf->getPath();
|
||||
getPaths().insert(path);
|
||||
|
||||
// Add or merge file state into directory state
|
||||
pathstate_map_t::iterator state_it = pathState.find(path);
|
||||
if(state_it != pathState.end())
|
||||
state_it.value() = static_cast<WorkspaceFile::Type>(state_it.value() | type);
|
||||
else
|
||||
{
|
||||
pathState.insert(path, type);
|
||||
paths.append(path); // keep path in list for depth sort
|
||||
}
|
||||
}
|
||||
|
||||
// Sort paths, so that children (longer path) are before parents (shorter path)
|
||||
std::sort(paths.begin(), paths.end(), StringLengthDescending);
|
||||
foreach(const QString &p, paths)
|
||||
{
|
||||
pathstate_map_t::iterator state_it = pathState.find(p);
|
||||
Q_ASSERT(state_it != pathState.end());
|
||||
WorkspaceFile::Type state = state_it.value();
|
||||
|
||||
// Propagate child dir state to parents
|
||||
QString parent_path = p;
|
||||
while(!parent_path.isEmpty())
|
||||
{
|
||||
// Extract parent path
|
||||
int sep_index = parent_path.lastIndexOf(PATH_SEPARATOR);
|
||||
if(sep_index>=0)
|
||||
parent_path = parent_path.left(sep_index);
|
||||
else
|
||||
parent_path = "";
|
||||
|
||||
// Merge path of child to parent
|
||||
pathstate_map_t::iterator state_it = pathState.find(parent_path);
|
||||
if(state_it != pathState.end())
|
||||
state_it.value() = static_cast<WorkspaceFile::Type>(state_it.value() | state);
|
||||
else
|
||||
pathState.insert(parent_path, state);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the repository needs integration
|
||||
res.clear();
|
||||
fossil().status(res);
|
||||
isIntegrated = false;
|
||||
foreach(const QString &l, res)
|
||||
{
|
||||
if(l.trimmed().indexOf("INTEGRATE")==0)
|
||||
{
|
||||
isIntegrated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Load the stashes, branches and tags
|
||||
fossil().stashList(getStashes());
|
||||
|
||||
fossil().branchList(branchList, branchList);
|
||||
|
||||
fossil().tagList(tags);
|
||||
// Fossil includes the branches in the tag list
|
||||
// So remove them
|
||||
foreach(const QString &name, branchList)
|
||||
tags.remove(name);
|
||||
|
||||
_done:
|
||||
uiCallback.endProcess();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Workspace::addRemote(const QUrl& url, const QString& name)
|
||||
{
|
||||
if(remotes.contains(url))
|
||||
return false;
|
||||
|
||||
Q_ASSERT(url.password().isEmpty());
|
||||
|
||||
Remote r(name, url);
|
||||
remotes.insert(url, r);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Workspace::removeRemote(const QUrl& url)
|
||||
{
|
||||
return remotes.remove(url) > 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Workspace::setRemoteDefault(const QUrl& url)
|
||||
{
|
||||
Q_ASSERT(url.password().isEmpty());
|
||||
|
||||
bool found = false;
|
||||
for(remote_map_t::iterator it=remotes.begin(); it!=remotes.end(); ++it)
|
||||
{
|
||||
if(it->url == url)
|
||||
{
|
||||
it->isDefault = true;
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
it->isDefault = false;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QUrl Workspace::getRemoteDefault() const
|
||||
{
|
||||
for(remote_map_t::const_iterator it=remotes.begin(); it!=remotes.end(); ++it)
|
||||
{
|
||||
if(it->isDefault)
|
||||
return it->url;
|
||||
}
|
||||
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Remote * Workspace::findRemote(const QUrl& url)
|
||||
{
|
||||
remote_map_t::iterator it = remotes.find(url);
|
||||
if(it!=remotes.end())
|
||||
return &(*it);
|
||||
return NULL;
|
||||
}
|
||||
|
180
src/Workspace.h
180
src/Workspace.h
@ -1,180 +0,0 @@
|
||||
#ifndef WORKSPACE_H
|
||||
#define WORKSPACE_H
|
||||
|
||||
#include <QStandardItemModel>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QSet>
|
||||
#include <QMap>
|
||||
#include <QSettings>
|
||||
#include "Utils.h"
|
||||
#include "Fossil.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WorkspaceFile
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct WorkspaceFile
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
TYPE_UNKNOWN = 1<<0,
|
||||
TYPE_UNCHANGED = 1<<1,
|
||||
TYPE_EDITTED = 1<<2,
|
||||
TYPE_ADDED = 1<<3,
|
||||
TYPE_DELETED = 1<<4,
|
||||
TYPE_MISSING = 1<<5,
|
||||
TYPE_RENAMED = 1<<6,
|
||||
TYPE_CONFLICTED = 1<<7,
|
||||
TYPE_MERGED = 1<<8,
|
||||
TYPE_MODIFIED = TYPE_EDITTED|TYPE_ADDED|TYPE_DELETED|TYPE_MISSING|TYPE_RENAMED|TYPE_CONFLICTED|TYPE_MERGED,
|
||||
TYPE_REPO = TYPE_UNCHANGED|TYPE_MODIFIED,
|
||||
TYPE_ALL = TYPE_UNKNOWN|TYPE_REPO
|
||||
};
|
||||
|
||||
WorkspaceFile(const QFileInfo &info, Type type, const QString &repoPath)
|
||||
{
|
||||
FileInfo = info;
|
||||
FileType = type;
|
||||
FilePath = getRelativeFilename(repoPath);
|
||||
Path = FileInfo.absolutePath();
|
||||
|
||||
// Strip the workspace path from the path
|
||||
Q_ASSERT(Path.indexOf(repoPath)==0);
|
||||
Path = Path.mid(repoPath.length()+1);
|
||||
}
|
||||
|
||||
bool isType(Type t) const
|
||||
{
|
||||
return FileType == t;
|
||||
}
|
||||
|
||||
void setType(Type t)
|
||||
{
|
||||
FileType = t;
|
||||
}
|
||||
|
||||
Type getType() const
|
||||
{
|
||||
return FileType;
|
||||
}
|
||||
|
||||
QFileInfo getFileInfo() const
|
||||
{
|
||||
return FileInfo;
|
||||
}
|
||||
|
||||
const QString &getFilePath() const
|
||||
{
|
||||
return FilePath;
|
||||
}
|
||||
|
||||
QString getFilename() const
|
||||
{
|
||||
return FileInfo.fileName();
|
||||
}
|
||||
|
||||
const QString &getPath() const
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
|
||||
QString getRelativeFilename(const QString &path)
|
||||
{
|
||||
QString abs_base_dir = QDir(path).absolutePath();
|
||||
|
||||
QString relative = FileInfo.absoluteFilePath();
|
||||
int index = relative.indexOf(abs_base_dir);
|
||||
if(index<0)
|
||||
return QString("");
|
||||
|
||||
return relative.right(relative.length() - abs_base_dir.length()-1);
|
||||
}
|
||||
|
||||
private:
|
||||
QFileInfo FileInfo;
|
||||
Type FileType;
|
||||
QString FilePath;
|
||||
QString Path;
|
||||
};
|
||||
|
||||
class Remote
|
||||
{
|
||||
public:
|
||||
Remote(const QString &_name, const QUrl &_url, bool _isDefault=false)
|
||||
: name(_name), url(_url), isDefault(_isDefault)
|
||||
{
|
||||
}
|
||||
|
||||
QString name;
|
||||
QUrl url;
|
||||
bool isDefault;
|
||||
|
||||
};
|
||||
|
||||
typedef QMap<QUrl, Remote> remote_map_t;
|
||||
typedef QMap<QString, WorkspaceFile::Type> pathstate_map_t;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Workspace
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class Workspace
|
||||
{
|
||||
public:
|
||||
Workspace();
|
||||
~Workspace();
|
||||
|
||||
typedef QList<WorkspaceFile*> filelist_t;
|
||||
typedef QMap<QString, WorkspaceFile*> filemap_t;
|
||||
|
||||
void clearState();
|
||||
|
||||
Fossil & fossil() { return bridge; }
|
||||
const Fossil & fossil() const { return bridge; }
|
||||
|
||||
const QString & getPath() const { return fossil().getWorkspacePath(); }
|
||||
bool switchWorkspace(const QString &workspace, QSettings &store);
|
||||
void scanWorkspace(bool scanLocal, bool scanIgnored, bool scanModified, bool scanUnchanged, const QStringList& ignorePatterns, UICallback &uiCallback, bool &operationAborted);
|
||||
|
||||
QStandardItemModel &getFileModel() { return repoFileModel; }
|
||||
QStandardItemModel &getTreeModel() { return repoTreeModel; }
|
||||
|
||||
filemap_t &getFiles() { return workspaceFiles; }
|
||||
stringset_t &getPaths() { return pathSet; }
|
||||
pathstate_map_t &getPathState() { return pathState; }
|
||||
stashmap_t &getStashes() { return stashMap; }
|
||||
QStringMap &getTags() { return tags; }
|
||||
QStringList &getBranches() { return branchList; }
|
||||
bool otherChanges() const { return isIntegrated; }
|
||||
const QString &getCurrentRevision() const { return fossil().getCurrentRevision(); }
|
||||
const QStringList &getActiveTags() const { return fossil().getActiveTags(); }
|
||||
const QString &getProjectName() const { return fossil().getProjectName(); }
|
||||
|
||||
// Remotes
|
||||
const remote_map_t &getRemotes() const { return remotes; }
|
||||
bool addRemote(const QUrl &url, const QString &name);
|
||||
bool removeRemote(const QUrl &url);
|
||||
bool setRemoteDefault(const QUrl& url);
|
||||
QUrl getRemoteDefault() const;
|
||||
Remote * findRemote(const QUrl& url);
|
||||
|
||||
void storeWorkspace(QSettings &store);
|
||||
private:
|
||||
static bool scanDirectory(QFileInfoList &entries, const QString& dirPath, const QString &baseDir, const QStringList& ignorePatterns, const bool& abort, UICallback &uiCallback);
|
||||
|
||||
private:
|
||||
Fossil bridge;
|
||||
filemap_t workspaceFiles;
|
||||
stringset_t pathSet;
|
||||
pathstate_map_t pathState;
|
||||
stashmap_t stashMap;
|
||||
QStringList branchList;
|
||||
QStringMap tags;
|
||||
remote_map_t remotes;
|
||||
bool isIntegrated;
|
||||
|
||||
QStandardItemModel repoFileModel;
|
||||
QStandardItemModel repoTreeModel;
|
||||
};
|
||||
|
||||
#endif // WORKSPACE_H
|
@ -5,7 +5,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
app.setApplicationName("Fuel");
|
||||
app.setApplicationVersion("2.0.0");
|
||||
app.setApplicationVersion("1.0.1");
|
||||
app.setOrganizationDomain("fuel-scm.org");
|
||||
app.setOrganizationName("Fuel-SCM");
|
||||
|
||||
|
@ -1,132 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AboutDialog</class>
|
||||
<widget class="QDialog" name="AboutDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>577</width>
|
||||
<height>349</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About Fuel...</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblIcon">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>64</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../rsrc/resources.qrc">:/icons/icon-application</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignHCenter|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblBanner">
|
||||
<property name="text">
|
||||
<string>A GUI front-end for the Fossil SCM by Kostas Karanikolas
|
||||
Released under the GNU GPL</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblFossilVersion">
|
||||
<property name="text">
|
||||
<string notr="true">FOSSIL VERSION</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lblQtVersion">
|
||||
<property name="text">
|
||||
<string notr="true">QT VERSION</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QTextEdit" name="txtAdditional">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../rsrc/resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>AboutDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AboutDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -14,16 +14,7 @@
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@ -53,7 +44,7 @@
|
||||
<action name="actionBrowserBack">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-previous</normaloff>:/icons/icon-action-previous</iconset>
|
||||
<normaloff>:/icons/icons/Button Previous-01.png</normaloff>:/icons/icons/Button Previous-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Back</string>
|
||||
@ -65,7 +56,7 @@
|
||||
<action name="actionBrowserForward">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-next</normaloff>:/icons/icon-action-next</iconset>
|
||||
<normaloff>:/icons/icons/Button Next-01.png</normaloff>:/icons/icons/Button Next-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Forward</string>
|
||||
@ -77,7 +68,7 @@
|
||||
<action name="actionBrowserRefresh">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-refresh</normaloff>:/icons/icon-action-refresh</iconset>
|
||||
<normaloff>:/icons/icons/Button Refresh-01.png</normaloff>:/icons/icons/Button Refresh-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Refresh</string>
|
||||
@ -89,7 +80,7 @@
|
||||
<action name="actionBrowserStop">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-stop</normaloff>:/icons/icon-action-stop</iconset>
|
||||
<normaloff>:/icons/icons/Button Close-01.png</normaloff>:/icons/icons/Button Close-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Stop</string>
|
||||
|
@ -10,7 +10,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>394</height>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -21,11 +21,7 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox">
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit"/>
|
||||
@ -66,99 +62,12 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetBranchOptions" native="true">
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Commit to new branch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkNewBranch">
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblPrivateBranch">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Private branch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="chkPrivateBranch">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Branch name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineBranchName">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkRevertFiles">
|
||||
<property name="text">
|
||||
<string>Revert stashed files</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
|
@ -1,272 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FslSettingsDialog</class>
|
||||
<widget class="QDialog" name="FslSettingsDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>457</width>
|
||||
<height>235</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Fossil Settings</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-application</normaloff>:/icons/icon-application</iconset>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Graphical Diff </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineGDiffCommand">
|
||||
<property name="toolTip">
|
||||
<string>Path to graphical diff tool</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSelectFossilGDiff">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Graphical Merge</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineGMergeCommand">
|
||||
<property name="toolTip">
|
||||
<string>Path to the graphical merge tool</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSelectGMerge">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_44">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>HTTP Proxy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineProxy">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The URL of the HTTP proxy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="uILanguageLabel_3">
|
||||
<property name="text">
|
||||
<string>HTTP Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="lineUIPort">
|
||||
<property name="toolTip">
|
||||
<string>HTTP port to use for the Fossil web interface</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ignore CR/NL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="lineIgnoreCRNL">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>A comma separated list of glob-style file patterns to exclude from Fossil's CR/NL consistency checking</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ignore List</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="lineIgnore">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>A comma separated list of glob-style file/path patterns ignored in Fossil file operations</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../rsrc/resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>FslSettingsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>FslSettingsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
350
ui/MainWindow.ui
350
ui/MainWindow.ui
@ -18,7 +18,7 @@
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-application</normaloff>:/icons/icon-application</iconset>
|
||||
<normaloff>:/icons/icons/Battery-01.png</normaloff>:/icons/icons/Battery-01.png</iconset>
|
||||
</property>
|
||||
<property name="unifiedTitleAndToolBarOnMac">
|
||||
<bool>true</bool>
|
||||
@ -38,7 +38,7 @@
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitterVertical">
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
@ -48,7 +48,7 @@
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QSplitter" name="splitterHorizontal">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
@ -58,7 +58,7 @@
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTreeView" name="workspaceTreeView">
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>20</horstretch>
|
||||
@ -66,7 +66,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
<enum>Qt::ActionsContextMenu</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
@ -78,13 +78,16 @@
|
||||
<enum>QAbstractItemView::SelectItems</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="headerShowSortIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="FileTableView" name="fileTableView">
|
||||
<widget class="FileTableView" name="tableView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>80</horstretch>
|
||||
@ -137,6 +140,44 @@
|
||||
<number>30</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QTableView" name="tableViewStash">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>20</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::ActionsContextMenu</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="showGrid">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="sizePolicy">
|
||||
@ -149,7 +190,7 @@
|
||||
<enum>QTabWidget::South</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabLog">
|
||||
<attribute name="title">
|
||||
@ -222,7 +263,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>865</width>
|
||||
<height>23</height>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@ -250,39 +291,16 @@
|
||||
<property name="title">
|
||||
<string>&View</string>
|
||||
</property>
|
||||
<addaction name="actionViewAll"/>
|
||||
<addaction name="actionViewModifedOnly"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionViewModified"/>
|
||||
<addaction name="actionViewUnchanged"/>
|
||||
<addaction name="actionViewUnknown"/>
|
||||
<addaction name="actionViewIgnored"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionViewStash"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionViewAsList"/>
|
||||
<addaction name="actionViewAsFolders"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuWorkspace">
|
||||
<property name="title">
|
||||
<string>&Workspace</string>
|
||||
</property>
|
||||
<addaction name="actionRefresh"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCommit"/>
|
||||
<addaction name="actionUpdate"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionPush"/>
|
||||
<addaction name="actionPull"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionUndo"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCreateBranch"/>
|
||||
<addaction name="actionCreateTag"/>
|
||||
<addaction name="actionCreateStash"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionFossilSettings"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuWorkspace"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
@ -325,6 +343,8 @@
|
||||
<addaction name="actionRevert"/>
|
||||
<addaction name="actionDelete"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionNewStash"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionDiff"/>
|
||||
<addaction name="actionHistory"/>
|
||||
<addaction name="separator"/>
|
||||
@ -337,10 +357,10 @@
|
||||
<action name="actionRefresh">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-refresh</normaloff>:/icons/icon-action-refresh</iconset>
|
||||
<normaloff>:/icons/icons/Button Refresh-01.png</normaloff>:/icons/icons/Button Refresh-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Refresh</string>
|
||||
<string>Refresh</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Refresh the views</string>
|
||||
@ -355,10 +375,10 @@
|
||||
<action name="actionCommit">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-commit</normaloff>:/icons/icon-action-commit</iconset>
|
||||
<normaloff>:/icons/icons/Save-01.png</normaloff>:/icons/icons/Save-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Commit</string>
|
||||
<string>Commit</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Commit modifications</string>
|
||||
@ -373,7 +393,7 @@
|
||||
<action name="actionDiff">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-item-diff</normaloff>:/icons/icon-item-diff</iconset>
|
||||
<normaloff>:/icons/icons/Document Copy-01.png</normaloff>:/icons/icons/Document Copy-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Diff</string>
|
||||
@ -391,7 +411,7 @@
|
||||
<action name="actionAdd">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-item-add</normaloff>:/icons/icon-item-add</iconset>
|
||||
<normaloff>:/icons/icons/File New-01.png</normaloff>:/icons/icons/File New-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
@ -409,7 +429,7 @@
|
||||
<action name="actionDelete">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-item-delete</normaloff>:/icons/icon-item-delete</iconset>
|
||||
<normaloff>:/icons/icons/File Delete-01.png</normaloff>:/icons/icons/File Delete-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
@ -427,7 +447,7 @@
|
||||
<action name="actionNewRepository">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-repo-new</normaloff>:/icons/icon-action-repo-new</iconset>
|
||||
<normaloff>:/icons/icons/Document Blank-01.png</normaloff>:/icons/icons/Document Blank-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&New...</string>
|
||||
@ -445,7 +465,7 @@
|
||||
<action name="actionOpenRepository">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-repo-open</normaloff>:/icons/icon-action-repo-open</iconset>
|
||||
<normaloff>:/icons/icons/My Documents-01.png</normaloff>:/icons/icons/My Documents-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Open...</string>
|
||||
@ -477,10 +497,10 @@
|
||||
<action name="actionCloneRepository">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-repo-clone</normaloff>:/icons/icon-action-repo-clone</iconset>
|
||||
<normaloff>:/icons/icons/My Websites-01.png</normaloff>:/icons/icons/My Websites-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>C&lone...</string>
|
||||
<string>Clone...</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Clone a remote repository</string>
|
||||
@ -489,13 +509,13 @@
|
||||
<action name="actionPush">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-push</normaloff>:/icons/icon-action-push</iconset>
|
||||
<normaloff>:/icons/icons/Button Upload-01.png</normaloff>:/icons/icons/Button Upload-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Push</string>
|
||||
<string>Push</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Push changes to the default remote repository</string>
|
||||
<string>Push changes to the remote repository</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Push changes to the remote repository</string>
|
||||
@ -507,13 +527,13 @@
|
||||
<action name="actionPull">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-pull</normaloff>:/icons/icon-action-pull</iconset>
|
||||
<normaloff>:/icons/icons/Button Download-01.png</normaloff>:/icons/icons/Button Download-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pu&ll</string>
|
||||
<string>Pull</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Pull changes from the default remote repository</string>
|
||||
<string>Pull changes from the remote repository</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Pull changes from the remote repository</string>
|
||||
@ -522,40 +542,10 @@
|
||||
<string>Ctrl+L</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPushRemote">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-push</normaloff>:/icons/icon-action-push</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Push to Remote</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Push changes to a remote repository</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Push changes to a remote repository</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPullRemote">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-pull</normaloff>:/icons/icon-action-pull</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pu&ll from Remote</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Pull changes from a remote repository</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Pull changes from a remote repository</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRename">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-item-rename</normaloff>:/icons/icon-item-rename</iconset>
|
||||
<normaloff>:/icons/icons/File Open-01.png</normaloff>:/icons/icons/File Open-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rename</string>
|
||||
@ -573,7 +563,7 @@
|
||||
<action name="actionQuit">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-quit</normaloff>:/icons/icon-action-quit</iconset>
|
||||
<normaloff>:/icons/icons/Button Turn Off-01.png</normaloff>:/icons/icons/Button Turn Off-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Quit</string>
|
||||
@ -594,7 +584,7 @@
|
||||
<action name="actionHistory">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-item-history</normaloff>:/icons/icon-item-history</iconset>
|
||||
<normaloff>:/icons/icons/File History-01.png</normaloff>:/icons/icons/File History-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>History</string>
|
||||
@ -615,7 +605,7 @@
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-webview</normaloff>:/icons/icon-webview</iconset>
|
||||
<normaloff>:/icons/icons/Network MAC-01.png</normaloff>:/icons/icons/Network MAC-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fossil UI</string>
|
||||
@ -630,7 +620,7 @@
|
||||
<action name="actionRevert">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-item-revert</normaloff>:/icons/icon-item-revert</iconset>
|
||||
<normaloff>:/icons/icons/Document-Revert-icon.png</normaloff>:/icons/icons/Document-Revert-icon.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Revert</string>
|
||||
@ -645,7 +635,7 @@
|
||||
<action name="actionClearLog">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-clear-log</normaloff>:/icons/icon-clear-log</iconset>
|
||||
<normaloff>:/icons/icons/Text Edit.png</normaloff>:/icons/icons/Text Edit.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear Log</string>
|
||||
@ -660,7 +650,7 @@
|
||||
<action name="actionTimeline">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-timeline</normaloff>:/icons/icon-action-timeline</iconset>
|
||||
<normaloff>:/icons/icons/Clock-01.png</normaloff>:/icons/icons/Clock-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Timeline</string>
|
||||
@ -675,7 +665,7 @@
|
||||
<action name="actionOpenFile">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-item-file</normaloff>:/icons/icon-item-file</iconset>
|
||||
<normaloff>:/icons/icons/Document-01.png</normaloff>:/icons/icons/Document-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open File</string>
|
||||
@ -693,7 +683,7 @@
|
||||
<action name="actionOpenContaining">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-folder-explore</normaloff>:/icons/icon-action-folder-explore</iconset>
|
||||
<normaloff>:/icons/icons/Folder-01.png</normaloff>:/icons/icons/Folder-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open Containing</string>
|
||||
@ -711,10 +701,10 @@
|
||||
<action name="actionUndo">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-undo</normaloff>:/icons/icon-action-undo</iconset>
|
||||
<normaloff>:/icons/icons/Button Reload-01.png</normaloff>:/icons/icons/Button Reload-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>U&ndo</string>
|
||||
<string>Undo</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Undo the last Fossil action</string>
|
||||
@ -729,7 +719,7 @@
|
||||
<action name="actionAbout">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-application</normaloff>:/icons/icon-application</iconset>
|
||||
<normaloff>:/icons/icons/Battery-01.png</normaloff>:/icons/icons/Battery-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&About...</string>
|
||||
@ -744,13 +734,13 @@
|
||||
<action name="actionUpdate">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-update</normaloff>:/icons/icon-action-update</iconset>
|
||||
<normaloff>:/icons/icons/Button Play-01.png</normaloff>:/icons/icons/Button Play-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Update</string>
|
||||
<string>Update</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Update the workspace to a revision</string>
|
||||
<string>Update the workspace to the latest version</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Update the workspace to the latest version</string>
|
||||
@ -762,7 +752,7 @@
|
||||
<action name="actionSettings">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-settings</normaloff>:/icons/icon-action-settings</iconset>
|
||||
<normaloff>:/icons/icons/Gear-01.png</normaloff>:/icons/icons/Gear-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Preferences...</string>
|
||||
@ -785,7 +775,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Modified Files</string>
|
||||
<string>&Modified</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Show modifed files</string>
|
||||
@ -799,7 +789,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Unchanged Files</string>
|
||||
<string>&Unchanged</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Show unchanged files</string>
|
||||
@ -813,7 +803,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Un&known Files</string>
|
||||
<string>Un&known</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Show unknown files</string>
|
||||
@ -824,7 +814,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Ignored Files</string>
|
||||
<string>&Ignored</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Show ignored files</string>
|
||||
@ -850,7 +840,7 @@
|
||||
<action name="actionOpenFolder">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-item-folder</normaloff>:/icons/icon-item-folder</iconset>
|
||||
<normaloff>:/icons/icons/Folder-01.png</normaloff>:/icons/icons/Folder-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open Folder</string>
|
||||
@ -865,7 +855,7 @@
|
||||
<action name="actionRenameFolder">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-folder-rename</normaloff>:/icons/icon-action-folder-rename</iconset>
|
||||
<normaloff>:/icons/icons/Folder Open-01.png</normaloff>:/icons/icons/Folder Open-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rename Folder</string>
|
||||
@ -877,13 +867,13 @@
|
||||
<string>Rename the selected folder</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateStash">
|
||||
<action name="actionNewStash">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-stash-new</normaloff>:/icons/icon-action-stash-new</iconset>
|
||||
<normaloff>:/icons/icons/Folder Add-01.png</normaloff>:/icons/icons/Folder Add-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Stash Changes</string>
|
||||
<string>Stash changes</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Stash changes</string>
|
||||
@ -892,7 +882,7 @@
|
||||
<action name="actionApplyStash">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-stash-apply</normaloff>:/icons/icon-action-stash-apply</iconset>
|
||||
<normaloff>:/icons/icons/Folder Open-01.png</normaloff>:/icons/icons/Folder Open-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply Stash</string>
|
||||
@ -904,10 +894,27 @@
|
||||
<string>Apply stashed changes</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewStash">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Stashed Changes</string>
|
||||
</property>
|
||||
<property name="iconText">
|
||||
<string>View Stashed Changes</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>View Stashed Changes</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Show the list of stashed changes</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDeleteStash">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-stash-delete</normaloff>:/icons/icon-action-stash-delete</iconset>
|
||||
<normaloff>:/icons/icons/Folder Delete-01.png</normaloff>:/icons/icons/Folder Delete-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete Stash</string>
|
||||
@ -916,137 +923,12 @@
|
||||
<action name="actionDiffStash">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-stash-diff</normaloff>:/icons/icon-action-stash-diff</iconset>
|
||||
<normaloff>:/icons/icons/Folder Explorer-01.png</normaloff>:/icons/icons/Folder Explorer-01.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Diff Stash</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateTag">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-tag-new</normaloff>:/icons/icon-action-tag-new</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create &Tag</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Create a tag for a revision</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Create a tag for a revision</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDeleteTag">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-tag-delete</normaloff>:/icons/icon-action-tag-delete</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete Tag</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Delete Tag</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateBranch">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-item-branch</normaloff>:/icons/icon-item-branch</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create &Branch</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Create a branch from a revision</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Create a branch from a revision</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMergeBranch">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-merge</normaloff>:/icons/icon-action-merge</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Merge Branch</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Merge with a branch</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Merge with a branch</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewAsFolders">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Files and F&olders</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>View files and folders</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>View the workspace as files and folders</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewAll">
|
||||
<property name="text">
|
||||
<string>&All Files</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Show all files</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewModifedOnly">
|
||||
<property name="text">
|
||||
<string>Mo&dified Files Only</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Show modified files only</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionFossilSettings">
|
||||
<property name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-action-settings</normaloff>:/icons/icon-action-settings</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>F&ossil Settings</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEditRemote">
|
||||
<property name="text">
|
||||
<string>Edit Remote</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Edit Remote URL</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSetDefaultRemote">
|
||||
<property name="text">
|
||||
<string>Set Remote as Default</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Makes the selected remote </string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddRemote">
|
||||
<property name="text">
|
||||
<string>Add Remote</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Adds a Remote Url</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDeleteRemote">
|
||||
<property name="text">
|
||||
<string>Delete Remote</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
@ -1,165 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RemoteDialog</class>
|
||||
<widget class="QDialog" name="RemoteDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>478</width>
|
||||
<height>189</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Remote Repository</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="text">
|
||||
<string>URL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineURL">
|
||||
<property name="toolTip">
|
||||
<string>The URL of the source repository</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSelectSourceRepo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>User Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineUserName">
|
||||
<property name="toolTip">
|
||||
<string>The user name used to access the remote repository. Leave blank if not required</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="linePassword">
|
||||
<property name="toolTip">
|
||||
<string>The password used to access the remote repository. Leave blank if not required</string>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="lineName">
|
||||
<property name="toolTip">
|
||||
<string>The password used to access the remote repository. Leave blank if not required</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="Name">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>lineURL</tabstop>
|
||||
<tabstop>btnSelectSourceRepo</tabstop>
|
||||
<tabstop>lineUserName</tabstop>
|
||||
<tabstop>linePassword</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>RemoteDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>RemoteDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -1,129 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RevisionDialog</class>
|
||||
<widget class="QDialog" name="RevisionDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>478</width>
|
||||
<height>177</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblRevision">
|
||||
<property name="text">
|
||||
<string>Revision</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cmbRevision">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblName">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineName"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblIntegrate">
|
||||
<property name="text">
|
||||
<string>Integrate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblForce">
|
||||
<property name="text">
|
||||
<string>Force</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="chkIntegrate">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="chkForce">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>RevisionDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>RevisionDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -9,23 +9,30 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>449</width>
|
||||
<height>428</height>
|
||||
<width>457</width>
|
||||
<height>352</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icon-application</normaloff>:/icons/icon-application</iconset>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabApp">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icons/Battery-01.png</normaloff>:/icons/icons/Battery-01.png</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string>Application</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
@ -71,137 +78,6 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Commit Messages</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="btnClearMessageHistory">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Clear the commit message history</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="uILanguageLabel_2">
|
||||
<property name="text">
|
||||
<string>Web Browser</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cmbFossilBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Web browser to use for the Fossil web interface</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Double-click Action</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="cmbDoubleClickAction">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Action to perfom when double-clicking a file</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="uILanguageLabel">
|
||||
<property name="text">
|
||||
<string>Language</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="cmbActiveLanguage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Language for the user interface</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Custom Actions</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Action</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cmbCustomAction">
|
||||
<property name="toolTip">
|
||||
<string>Custom action</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineCustomActionDescription">
|
||||
<property name="toolTip">
|
||||
<string>Name of custom action</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -210,34 +86,21 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Description</string>
|
||||
<string>Graphical Diff </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Command</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineCustomActionCommand">
|
||||
<widget class="QLineEdit" name="lineGDiffCommand">
|
||||
<property name="toolTip">
|
||||
<string>Custom action command-line. Information about the selected items is available via the macros %FILE %FOLDER %WORKSPACE</string>
|
||||
<string>Path to graphical diff tool</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSelectCustomFileActionCommand">
|
||||
<widget class="QPushButton" name="btnSelectFossilGDiff">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@ -257,42 +120,287 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Context</string>
|
||||
<string>Graphical Merge</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineGMergeCommand">
|
||||
<property name="toolTip">
|
||||
<string>Path to the graphical merge tool</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSelectGMerge">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_44">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>HTTP Proxy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="lineProxy">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The URL of the HTTP proxy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="uILanguageLabel_3">
|
||||
<property name="text">
|
||||
<string>HTTP Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="cmbCustomActionContext">
|
||||
<widget class="QLineEdit" name="lineUIPort">
|
||||
<property name="toolTip">
|
||||
<string>The context where this action will be available</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="chkCustomActionMultipleSelection">
|
||||
<property name="toolTip">
|
||||
<string>When checked this action supports multiple selected items</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>HTTP port to use for the Fossil web interface</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Multiple Selection</string>
|
||||
<string>Commit Messages</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QPushButton" name="btnClearMessageHistory">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Clear the commit message history</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="uILanguageLabel_2">
|
||||
<property name="text">
|
||||
<string>Web Browser</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="cmbFossilBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Web browser to use for the Fossil web interface</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Double-click Action</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QComboBox" name="cmbDoubleClickAction">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Action to perfom when double-clicking a file</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="uILanguageLabel">
|
||||
<property name="text">
|
||||
<string>Language</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QComboBox" name="cmbActiveLanguage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Language for the user interface</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabRepo">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../rsrc/resources.qrc">
|
||||
<normaloff>:/icons/icons/Book-01.png</normaloff>:/icons/icons/Book-01.png</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string>Repository</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remote Url</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineRemoteURL">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The remote url used to push/pull changes.
|
||||
URL style user names and passwords are also supported.
|
||||
For example http://username:password@server.com/fossil</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ignore List</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineIgnore">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>A comma separated list of glob-style file/path patterns ignored in Fossil file operations</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ignore CR/NL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineIgnoreCRNL">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>A comma separated list of glob-style file patterns to exclude from Fossil's CR/NL consistency checking</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
|
Reference in New Issue
Block a user