mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-27 20:58:47 +00:00
Merge branch 'Qt'
After the 3.1 release it is time to shift the focus on the Qt effort - and the best way to do this is to merge the changes in the Qt branch into master. Linus was extremely nice and did a merge for me. I decided to do my own merge instead (which by accident actually based on a different version of the Qt branch) and then used his merge to double check what I was doing. I resolved a few things differently but overall what we did was very much the same (and I say this with pride since Linus is a professional git merger) Here's his merge commit message: This is a rough and tumble merge of the Qt branch into 'master', trying to sort out the conflicts as best as I could. There were two major kinds of conflicts: - the Makefile changes, in particular the split of the single Makefile into Rules.mk and Configure.mk, along with the obvious Qt build changes themselves. Those changes conflicted with some of the updates done in mainline wrt "release" targets and some helper macros ($(NAME) etc). Resolved by largely taking the Qt branch versions, and then editing in the most obvious parts of the Makefile updates from mainline. NOTE! The script/get_version shell script was made to just fail silently on not finding a git repository, which avoided having to take some particularly ugly Makefile changes. - Various random updates in mainline to support things like dive tags. The conflicts were mainly to the gtk GUI parts, which obviously looked different afterwards. I fixed things up to look like the newer code, but since the gtk files themselves are actually dead in the Qt branch, this is largely irrelevant. NOTE! This does *NOT* introduce the equivalent Qt functionality. The fields are there in the code now, but there's no Qt UI for the whole dive tag stuff etc. This seems to compile for me (although I have to force "QMAKE=qmake-qt4" on f19), and results in a Linux binary that seems to work, but it is otherwise largely untested. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
commit
f3f7bf51fa
67 changed files with 7313 additions and 1707 deletions
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -3,12 +3,16 @@
|
|||
*.rej
|
||||
*.exe
|
||||
*.dmg
|
||||
*.moc
|
||||
*.moc.cpp
|
||||
*.patch
|
||||
*.ui.h
|
||||
*.xml
|
||||
version.h
|
||||
!dives/*.xml
|
||||
*~
|
||||
po/*.mo
|
||||
qt-ui/ui_*.h
|
||||
/subsurface
|
||||
/*.tar.gz
|
||||
.dep/
|
||||
|
@ -19,3 +23,10 @@ Documentation/user-manual.pdf
|
|||
Documentation/user-manual.text
|
||||
packaging/windows/subsurface.nsi
|
||||
packaging/macos/Info.plist
|
||||
config.cache
|
||||
*.qrc.cpp
|
||||
/subsurface.config
|
||||
/subsurface.creator
|
||||
/subsurface.creator.user
|
||||
/subsurface.files
|
||||
/subsurface.includes
|
||||
|
|
195
Configure.mk
Normal file
195
Configure.mk
Normal file
|
@ -0,0 +1,195 @@
|
|||
# -*- Makefile -*-
|
||||
# This file contains the detection rules
|
||||
all:
|
||||
|
||||
PKGCONFIG=pkg-config
|
||||
XML2CONFIG=xml2-config
|
||||
XSLCONFIG=xslt-config
|
||||
QMAKE=qmake
|
||||
MOC=moc
|
||||
UIC=uic
|
||||
|
||||
CONFIGFILE = config.cache
|
||||
ifeq ($(CONFIGURING),1)
|
||||
|
||||
# Detect the target system
|
||||
# Ask the compiler what OS it's producing files for
|
||||
UNAME := $(shell $(CC) -dumpmachine 2>&1 | grep -E -o "linux|darwin|win|gnu|kfreebsd")
|
||||
|
||||
# find libdivecomputer
|
||||
# First deal with the cross compile environment and with Mac.
|
||||
# For the native case, Linus doesn't want to trust pkg-config given
|
||||
# how young libdivecomputer still is - so we check the typical
|
||||
# subdirectories of /usr/local and /usr and then we give up. You can
|
||||
# override by simply setting it here
|
||||
#
|
||||
ifeq ($(CC), i686-w64-mingw32-gcc)
|
||||
# ok, we are cross building for Windows
|
||||
LIBDIVECOMPUTERINCLUDES = $(shell $(PKGCONFIG) --cflags libdivecomputer)
|
||||
LIBDIVECOMPUTERARCHIVE = $(shell $(PKGCONFIG) --libs libdivecomputer)
|
||||
RESFILE = packaging/windows/subsurface.res
|
||||
LDFLAGS += -Wl,-subsystem,windows
|
||||
LIBWINSOCK = -lwsock32
|
||||
else ifeq ($(UNAME), darwin)
|
||||
LIBDIVECOMPUTERINCLUDES = $(shell $(PKGCONFIG) --cflags libdivecomputer)
|
||||
LIBDIVECOMPUTERARCHIVE = $(shell $(PKGCONFIG) --libs libdivecomputer)
|
||||
else
|
||||
libdc-local := $(wildcard /usr/local/lib/libdivecomputer.a)
|
||||
libdc-local64 := $(wildcard /usr/local/lib64/libdivecomputer.a)
|
||||
libdc-usr := $(wildcard /usr/lib/libdivecomputer.a)
|
||||
libdc-usr64 := $(wildcard /usr/lib64/libdivecomputer.a)
|
||||
|
||||
ifneq ($(LIBDCDEVEL),)
|
||||
LIBDIVECOMPUTERDIR = ../libdivecomputer
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/src/.libs/libdivecomputer.a
|
||||
else ifneq ($(strip $(libdc-local)),)
|
||||
LIBDIVECOMPUTERDIR = /usr/local
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib/libdivecomputer.a
|
||||
else ifneq ($(strip $(libdc-local64)),)
|
||||
LIBDIVECOMPUTERDIR = /usr/local
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib64/libdivecomputer.a
|
||||
else ifneq ($(strip $(libdc-usr)),)
|
||||
LIBDIVECOMPUTERDIR = /usr
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib/libdivecomputer.a
|
||||
else ifneq ($(strip $(libdc-usr64)),)
|
||||
LIBDIVECOMPUTERDIR = /usr
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib64/libdivecomputer.a
|
||||
else
|
||||
$(error Cannot find libdivecomputer - please edit Makefile)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Libusb-1.0 is only required if libdivecomputer was built with it.
|
||||
# And libdivecomputer is only built with it if libusb-1.0 is
|
||||
# installed. So get libusb if it exists, but don't complain
|
||||
# about it if it doesn't.
|
||||
LIBUSB = $(shell $(PKGCONFIG) --libs libusb-1.0 2> /dev/null)
|
||||
|
||||
# Find qmake. Rules are:
|
||||
# - use qmake if it is in $PATH
|
||||
# [qmake -query QT_VERSION will fail if it's Qt 3's qmake]
|
||||
# - if that fails, try qmake-qt4
|
||||
# - if that fails, print an error
|
||||
# We specifically do not search for qmake-qt5 since that is not supposed
|
||||
# to exist.
|
||||
QMAKE = $(shell { qmake -query QT_VERSION >/dev/null 2>&1 && echo qmake; } || \
|
||||
{ qmake-qt4 -v >/dev/null 2>&1 && echo qmake-qt4; })
|
||||
ifeq ($(strip $(QMAKE)),)
|
||||
$(error Could not find qmake or qmake-qt4 in $$PATH or they failed)
|
||||
endif
|
||||
|
||||
# Use qmake to find out which Qt version we are building for.
|
||||
QT_VERSION_MAJOR = $(shell $(QMAKE) -query QT_VERSION | cut -d. -f1)
|
||||
ifeq ($(QT_VERSION_MAJOR), 5)
|
||||
# QT_MODULES = Qt5Widgets Qt5Svg
|
||||
# QT_CORE = Qt5Core
|
||||
# QTBINDIR = $(shell $(QMAKE) -query QT_HOST_BINS)
|
||||
# # Tool paths are not stored in .pc files in Qt 5.0
|
||||
# MOC = $(QTBINDIR)/moc
|
||||
# UIC = $(QTBINDIR)/uic
|
||||
# RCC = $(QTBINDIR)/rcc
|
||||
# if qmake is qt5, try to get the qt4 one.
|
||||
QMAKE = { qmake-qt4 -v >/dev/null 2>&1 && echo qmake-qt4; }
|
||||
#else
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(QMAKE)),)
|
||||
$(error Could not find qmake or qmake-qt4 in $$PATH for the Qt4 version they failed)
|
||||
endif
|
||||
|
||||
QT_MODULES = QtGui QtSvg
|
||||
QT_CORE = QtCore
|
||||
MOC = $(shell $(PKGCONFIG) --variable=moc_location QtCore)
|
||||
UIC = $(shell $(PKGCONFIG) --variable=uic_location QtGui)
|
||||
RCC = $(shell $(PKGCONFIG) --variable=rcc_location QtGui)
|
||||
#endif
|
||||
|
||||
# we need GLIB2CFLAGS for gettext
|
||||
QTCXXFLAGS = $(shell $(PKGCONFIG) --cflags $(QT_MODULES)) $(GLIB2CFLAGS)
|
||||
LIBQT = $(shell $(PKGCONFIG) --libs $(QT_MODULES))
|
||||
ifneq ($(filter reduce_relocations, $(shell $(PKGCONFIG) --variable qt_config $(QT_CORE))), )
|
||||
QTCXXFLAGS += -fPIE
|
||||
endif
|
||||
|
||||
LIBGTK = $(shell $(PKGCONFIG) --libs gtk+-2.0 glib-2.0)
|
||||
ifneq (,$(filter $(UNAME),linux kfreebsd gnu))
|
||||
LIBGCONF2 = $(shell $(PKGCONFIG) --libs gconf-2.0)
|
||||
GCONF2CFLAGS = $(shell $(PKGCONFIG) --cflags gconf-2.0)
|
||||
else ifeq ($(UNAME), darwin)
|
||||
LIBGTK += $(shell $(PKGCONFIG) --libs gtk-mac-integration) -framework CoreFoundation -framework CoreServices
|
||||
GTKCFLAGS += $(shell $(PKGCONFIG) --cflags gtk-mac-integration)
|
||||
GTK_MAC_BUNDLER = ~/.local/bin/gtk-mac-bundler
|
||||
endif
|
||||
|
||||
LIBDIVECOMPUTERCFLAGS = $(LIBDIVECOMPUTERINCLUDES)
|
||||
LIBDIVECOMPUTER = $(LIBDIVECOMPUTERARCHIVE) $(LIBUSB)
|
||||
|
||||
LIBXML2 = $(shell $(XML2CONFIG) --libs)
|
||||
LIBXSLT = $(shell $(XSLCONFIG) --libs)
|
||||
XML2CFLAGS = $(shell $(XML2CONFIG) --cflags)
|
||||
GLIB2CFLAGS = $(shell $(PKGCONFIG) --cflags glib-2.0)
|
||||
GTKCFLAGS += $(shell $(PKGCONFIG) --cflags gtk+-2.0)
|
||||
XSLCFLAGS = $(shell $(XSLCONFIG) --cflags)
|
||||
OSMGPSMAPFLAGS += $(shell $(PKGCONFIG) --cflags osmgpsmap 2> /dev/null)
|
||||
LIBOSMGPSMAP += $(shell $(PKGCONFIG) --libs osmgpsmap 2> /dev/null)
|
||||
LIBSOUPCFLAGS = $(shell $(PKGCONFIG) --cflags libsoup-2.4)
|
||||
LIBSOUP = $(shell $(PKGCONFIG) --libs libsoup-2.4)
|
||||
|
||||
LIBZIP = $(shell $(PKGCONFIG) --libs libzip 2> /dev/null)
|
||||
ZIPFLAGS = $(strip $(shell $(PKGCONFIG) --cflags libzip 2> /dev/null))
|
||||
|
||||
LIBSQLITE3 = $(shell $(PKGCONFIG) --libs sqlite3 2> /dev/null)
|
||||
SQLITE3FLAGS = $(strip $(shell $(PKGCONFIG) --cflags sqlite3))
|
||||
|
||||
# Write the configure file
|
||||
all: configure
|
||||
configure $(CONFIGURE): Configure.mk
|
||||
@echo "\
|
||||
CONFIGURED = 1\\\
|
||||
UNAME = $(UNAME)\\\
|
||||
LIBDIVECOMPUTERDIR = $(LIBDIVECOMPUTERDIR)\\\
|
||||
LIBDIVECOMPUTERCFLAGS = $(LIBDIVECOMPUTERCFLAGS)\\\
|
||||
LIBDIVECOMPUTER = $(LIBDIVECOMPUTER)\\\
|
||||
LIBWINSOCK = $(LIBWINSOCK)\\\
|
||||
LDFLAGS = $(LDFLAGS)\\\
|
||||
RESFILE = $(RESFILE)\\\
|
||||
LIBQT = $(LIBQT)\\\
|
||||
QTCXXFLAGS = $(QTCXXFLAGS)\\\
|
||||
MOC = $(MOC)\\\
|
||||
UIC = $(UIC)\\\
|
||||
RCC = $(RCC)\\\
|
||||
LIBGTK = $(LIBGTK)\\\
|
||||
GTKCFLAGS = $(GTKCFLAGS)\\\
|
||||
LIBGCONF2 = $(LIBGCONF2)\\\
|
||||
GCONF2CFLAGS = $(GCONF2CFLAGS)\\\
|
||||
GTK_MAC_BUNDLER = $(GTK_MAC_BUNDLER)\\\
|
||||
LIBXML2 = $(LIBXML2)\\\
|
||||
LIBXSLT = $(LIBXSLT)\\\
|
||||
XML2CFLAGS = $(XML2CFLAGS)\\\
|
||||
GLIB2CFLAGS = $(GLIB2CFLAGS)\\\
|
||||
XSLCFLAGS = $(XSLCFLAGS)\\\
|
||||
OSMGPSMAPFLAGS = $(OSMGPSMAPFLAGS)\\\
|
||||
LIBOSMGPSMAP = $(LIBOSMGPSMAP)\\\
|
||||
LIBSOUPCFLAGS = $(LIBSOUPCFLAGS)\\\
|
||||
LIBSOUP = $(LIBSOUP)\\\
|
||||
LIBZIP = $(LIBZIP)\\\
|
||||
ZIPFLAGS = $(ZIPFLAGS)\\\
|
||||
LIBSQLITE3 = $(LIBSQLITE3)\\\
|
||||
SQLITE3FLAGS = $(SQLITE3FLAGS)\\\
|
||||
" | tr '\\' '\n' > $(CONFIGFILE)
|
||||
|
||||
else
|
||||
configure $(CONFIGFILE): Configure.mk
|
||||
@test -e $(CONFIGFILE) && echo Reconfiguring.. || echo Configuring...
|
||||
@$(MAKE) CONFIGURING=1 configure
|
||||
@echo Done
|
||||
|
||||
-include $(CONFIGFILE)
|
||||
endif
|
||||
|
||||
.PHONY: configure all
|
358
Makefile
358
Makefile
|
@ -2,14 +2,14 @@ NAME = subsurface
|
|||
CAPITALIZED_NAME = Subsurface
|
||||
TARGET = $(NAME)
|
||||
|
||||
include Configure.mk
|
||||
VERSION=3.1
|
||||
|
||||
CC=gcc
|
||||
CFLAGS=-Wall -Wno-pointer-sign -g $(CLCFLAGS) -DGSEAL_ENABLE
|
||||
CXX=g++
|
||||
CXXFLAGS=-Wall -g $(CLCXXFLAGS) -DQT_NO_KEYWORDS
|
||||
INSTALL=install
|
||||
PKGCONFIG=pkg-config
|
||||
XML2CONFIG=xml2-config
|
||||
XSLCONFIG=xslt-config
|
||||
|
||||
# these locations seem to work for SuSE and Fedora
|
||||
# prefix = $(HOME)
|
||||
|
@ -28,141 +28,86 @@ DESKTOPFILE = $(NAME).desktop
|
|||
MANFILES = $(NAME).1
|
||||
XSLTFILES = xslt/*.xslt xslt/*.xsl
|
||||
|
||||
VERSION_FILE = version.h
|
||||
# There's only one line in $(VERSION_FILE); use the shell builtin `read'
|
||||
STORED_VERSION_STRING = \
|
||||
$(subst ",,$(shell [ ! -r $(VERSION_FILE) ] || \
|
||||
read ignore ignore v <$(VERSION_FILE) && echo $$v))
|
||||
#" workaround editor syntax highlighting quirk
|
||||
EXTRA_FLAGS = $(QTCXXFLAGS) $(GTKCFLAGS) $(GLIB2CFLAGS) $(XML2CFLAGS) \
|
||||
$(LIBDIVECOMPUTERCFLAGS) \
|
||||
$(LIBSOUPCFLAGS) $(GCONF2CFLAGS)
|
||||
|
||||
UNAME := $(shell $(CC) -dumpmachine 2>&1 | grep -E -o "linux|darwin|win|gnu|kfreebsd")
|
||||
GET_VERSION = ./scripts/get-version
|
||||
VERSION_STRING := $(shell [ -d .git ] && $(GET_VERSION) linux || \
|
||||
echo "v$(VERSION)")
|
||||
# Mac Info.plist style with three numbers 1.2.3
|
||||
CFBUNDLEVERSION_STRING := $(shell [ -d .git ] && \
|
||||
$(GET_VERSION) darwin $(VERSION_STRING) || \
|
||||
echo "$(VERSION).0")
|
||||
# Windows .nsi style with four numbers 1.2.3.4
|
||||
PRODVERSION_STRING := $(shell [ -d .git ] && \
|
||||
$(GET_VERSION) win $(VERSION_STRING) || \
|
||||
echo "$(VERSION).0.0")
|
||||
HEADERS = \
|
||||
qt-ui/addcylinderdialog.h \
|
||||
qt-ui/addweightsystemdialog.h \
|
||||
qt-ui/divelistview.h \
|
||||
qt-ui/maintab.h \
|
||||
qt-ui/mainwindow.h \
|
||||
qt-ui/models.h \
|
||||
qt-ui/plotareascene.h \
|
||||
qt-ui/starwidget.h \
|
||||
qt-ui/modeldelegates.h \
|
||||
qt-ui/profilegraphics.h \
|
||||
qt-ui/globe.h
|
||||
|
||||
# 'pretty' output (easy to spot warnings) by default
|
||||
# 'verbose' output (all the details) by calling with "make V=1"
|
||||
ifeq ($(V),1)
|
||||
PRETTYECHO=true
|
||||
COMPILE_PREFIX=
|
||||
else
|
||||
PRETTYECHO=echo
|
||||
COMPILE_PREFIX=@
|
||||
|
||||
SOURCES = \
|
||||
deco.c \
|
||||
device.c \
|
||||
dive.c \
|
||||
divelist.c \
|
||||
download-dialog.c \
|
||||
equipment.c \
|
||||
file.c \
|
||||
info.c \
|
||||
main.c \
|
||||
parse-xml.c \
|
||||
prefs.c \
|
||||
profile.c \
|
||||
save-xml.c \
|
||||
sha1.c \
|
||||
statistics.c \
|
||||
time.c \
|
||||
qt-gui.cpp \
|
||||
qt-ui/addcylinderdialog.cpp \
|
||||
qt-ui/addweightsystemdialog.cpp \
|
||||
qt-ui/divelistview.cpp \
|
||||
qt-ui/maintab.cpp \
|
||||
qt-ui/mainwindow.cpp \
|
||||
qt-ui/models.cpp \
|
||||
qt-ui/plotareascene.cpp \
|
||||
qt-ui/starwidget.cpp \
|
||||
qt-ui/modeldelegates.cpp \
|
||||
qt-ui/profilegraphics.cpp \
|
||||
qt-ui/globe.cpp \
|
||||
$(RESFILE)
|
||||
|
||||
|
||||
RESOURCES = $(NAME).qrc
|
||||
|
||||
ifneq ($(SQLITE3FLAGS),)
|
||||
EXTRA_FLAGS += -DSQLITE3 $(SQLITE3FLAGS)
|
||||
endif
|
||||
|
||||
# find libdivecomputer
|
||||
# First deal with the cross compile environment and with Mac.
|
||||
# For the native case, Linus doesn't want to trust pkg-config given
|
||||
# how young libdivecomputer still is - so we check the typical
|
||||
# subdirectories of /usr/local and /usr and then we give up. You can
|
||||
# override by simply setting it here
|
||||
#
|
||||
ifeq ($(CC), i686-w64-mingw32-gcc)
|
||||
# ok, we are cross building for Windows
|
||||
LIBDIVECOMPUTERINCLUDES = $(shell $(PKGCONFIG) --cflags libdivecomputer)
|
||||
LIBDIVECOMPUTERARCHIVE = $(shell $(PKGCONFIG) --libs libdivecomputer)
|
||||
LIBGNUTLS = $(shell $(PKGCONFIG) --libs gnutls-extra) $(shell $(PKGCONFIG) --libs p11-kit-1)
|
||||
RESFILE = packaging/windows/$(NAME).res
|
||||
LDFLAGS += -Wl,-subsystem,windows
|
||||
LIBWINSOCK = -lwsock32
|
||||
TARGET = $(NAME).exe
|
||||
else ifeq ($(UNAME), darwin)
|
||||
LIBDIVECOMPUTERINCLUDES = $(shell $(PKGCONFIG) --cflags libdivecomputer)
|
||||
LIBDIVECOMPUTERARCHIVE = $(shell $(PKGCONFIG) --libs libdivecomputer)
|
||||
else
|
||||
libdc-local := $(wildcard /usr/local/lib/libdivecomputer.a)
|
||||
libdc-local64 := $(wildcard /usr/local/lib64/libdivecomputer.a)
|
||||
libdc-usr := $(wildcard /usr/lib/libdivecomputer.a)
|
||||
libdc-usr64 := $(wildcard /usr/lib64/libdivecomputer.a)
|
||||
|
||||
ifneq ($(LIBDCDEVEL),)
|
||||
LIBDIVECOMPUTERDIR = ../libdivecomputer
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/src/.libs/libdivecomputer.a
|
||||
else ifneq ($(strip $(libdc-local)),)
|
||||
LIBDIVECOMPUTERDIR = /usr/local
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib/libdivecomputer.a
|
||||
else ifneq ($(strip $(libdc-local64)),)
|
||||
LIBDIVECOMPUTERDIR = /usr/local
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib64/libdivecomputer.a
|
||||
else ifneq ($(strip $(libdc-usr)),)
|
||||
LIBDIVECOMPUTERDIR = /usr
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib/libdivecomputer.a
|
||||
else ifneq ($(strip $(libdc-usr64)),)
|
||||
LIBDIVECOMPUTERDIR = /usr
|
||||
LIBDIVECOMPUTERINCLUDES = -I$(LIBDIVECOMPUTERDIR)/include
|
||||
LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib64/libdivecomputer.a
|
||||
else
|
||||
$(error Cannot find libdivecomputer - please edit Makefile)
|
||||
ifneq ($(ZIPFLAGS),)
|
||||
EXTRA_FLAGS += -DLIBZIP $(ZIPFLAGS)
|
||||
endif
|
||||
ifneq ($(strip $(LIBXSLT)),)
|
||||
EXTRA_FLAGS += -DXSLT='"$(XSLTDIR)"' $(XSLCFLAGS)
|
||||
endif
|
||||
|
||||
# Libusb-1.0 is only required if libdivecomputer was built with it.
|
||||
# And libdivecomputer is only built with it if libusb-1.0 is
|
||||
# installed. So get libusb if it exists, but don't complain
|
||||
# about it if it doesn't.
|
||||
LIBUSB = $(shell $(PKGCONFIG) --libs libusb-1.0 2> /dev/null)
|
||||
|
||||
LIBGTK = $(shell $(PKGCONFIG) --libs gtk+-2.0 glib-2.0)
|
||||
LIBDIVECOMPUTERCFLAGS = $(LIBDIVECOMPUTERINCLUDES)
|
||||
LIBDIVECOMPUTER = $(LIBDIVECOMPUTERARCHIVE) $(LIBUSB)
|
||||
|
||||
LIBXML2 = $(shell $(XML2CONFIG) --libs)
|
||||
LIBXSLT = $(shell $(XSLCONFIG) --libs)
|
||||
XML2CFLAGS = $(shell $(XML2CONFIG) --cflags)
|
||||
GLIB2CFLAGS = $(shell $(PKGCONFIG) --cflags glib-2.0)
|
||||
GTKCFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-2.0)
|
||||
CFLAGS += $(shell $(XSLCONFIG) --cflags)
|
||||
OSMGPSMAPFLAGS += $(shell $(PKGCONFIG) --cflags osmgpsmap 2> /dev/null)
|
||||
LIBOSMGPSMAP += $(shell $(PKGCONFIG) --libs osmgpsmap 2> /dev/null)
|
||||
ifeq ($(USE_GTK_UI),1)
|
||||
ifneq ($(strip $(LIBOSMGPSMAP)),)
|
||||
GPSOBJ = gps.o
|
||||
CFLAGS += -DHAVE_OSM_GPS_MAP
|
||||
SOURCES += gps.c
|
||||
EXTRA_FLAGS += -DHAVE_OSM_GPS_MAP $(OSMGPSMAPFLAGS)
|
||||
endif
|
||||
LIBSOUPCFLAGS = $(shell $(PKGCONFIG) --cflags libsoup-2.4)
|
||||
LIBSOUP = $(shell $(PKGCONFIG) --libs libsoup-2.4)
|
||||
|
||||
LIBZIP = $(shell $(PKGCONFIG) --libs libzip 2> /dev/null)
|
||||
ifneq ($(strip $(LIBZIP)),)
|
||||
ZIP = -DLIBZIP $(shell $(PKGCONFIG) --cflags libzip)
|
||||
endif
|
||||
|
||||
LIBSQLITE3 = $(shell $(PKGCONFIG) --libs sqlite3 2> /dev/null)
|
||||
ifneq ($(strip $(LIBSQLITE3)),)
|
||||
SQLITE3 = -DSQLITE3 $(shell $(PKGCONFIG) --cflags sqlite3)
|
||||
endif
|
||||
|
||||
ifneq (,$(filter $(UNAME),linux kfreebsd gnu))
|
||||
LIBGCONF2 = $(shell $(PKGCONFIG) --libs gconf-2.0)
|
||||
GCONF2CFLAGS = $(shell $(PKGCONFIG) --cflags gconf-2.0)
|
||||
OSSUPPORT = linux
|
||||
OSSUPPORT_CFLAGS = $(GTKCFLAGS) $(GCONF2CFLAGS)
|
||||
SOURCES += linux.c
|
||||
else ifeq ($(UNAME), darwin)
|
||||
OSSUPPORT = macos
|
||||
OSSUPPORT_CFLAGS = $(GTKCFLAGS)
|
||||
SOURCES += macos.c
|
||||
MACOSXINSTALL = /Applications/$(CAPITALIZED_NAME).app
|
||||
MACOSXFILES = packaging/macosx
|
||||
MACOSXSTAGING = $(MACOSXFILES)/$(CAPITALIZED_NAME).app
|
||||
INFOPLIST = $(MACOSXFILES)/Info.plist
|
||||
INFOPLISTINPUT = $(INFOPLIST).in
|
||||
EXTRALIBS = $(shell $(PKGCONFIG) --libs gtk-mac-integration) -framework CoreFoundation -framework CoreServices
|
||||
CFLAGS += $(shell $(PKGCONFIG) --cflags gtk-mac-integration)
|
||||
LDFLAGS += -headerpad_max_install_names -sectcreate __TEXT __info_plist $(INFOPLIST)
|
||||
GTK_MAC_BUNDLER = ~/.local/bin/gtk-mac-bundler
|
||||
LDFLAGS += -headerpad_max_install_names
|
||||
else
|
||||
OSSUPPORT = windows
|
||||
OSSUPPORT_CFLAGS = $(GTKCFLAGS)
|
||||
SOURCES += windows.c
|
||||
WINDOWSSTAGING = ./packaging/windows
|
||||
WINMSGDIRS=$(addprefix share/locale/,$(shell ls po/*.po | sed -e 's/po\/\(..\)_.*/\1\/LC_MESSAGES/'))
|
||||
NSIINPUTFILE = $(WINDOWSSTAGING)/$(NAME).nsi.in
|
||||
|
@ -171,170 +116,15 @@ else
|
|||
XSLTDIR = .\\xslt
|
||||
endif
|
||||
|
||||
ifneq ($(strip $(LIBXSLT)),)
|
||||
XSLT=-DXSLT='"$(XSLTDIR)"'
|
||||
endif
|
||||
|
||||
LIBS = $(LIBXML2) $(LIBXSLT) $(LIBSQLITE3) $(LIBGTK) $(LIBGCONF2) $(LIBDIVECOMPUTER) $(EXTRALIBS) $(LIBZIP) -lpthread -lm $(LIBOSMGPSMAP) $(LIBSOUP) $(LIBWINSOCK) $(LIBGNUTLS)
|
||||
LIBS = $(LIBQT) $(LIBXML2) $(LIBXSLT) $(LIBSQLITE3) $(LIBGCONF2) $(LIBDIVECOMPUTER) \
|
||||
$(EXTRALIBS) $(LIBZIP) -lpthread -lm $(LIBOSMGPSMAP) $(LIBSOUP) $(LIBWINSOCK) -lmarblewidget
|
||||
|
||||
MSGLANGS=$(notdir $(wildcard po/*.po))
|
||||
MSGOBJS=$(addprefix share/locale/,$(MSGLANGS:.po=.UTF-8/LC_MESSAGES/$(NAME).mo))
|
||||
|
||||
GTKOBJS = info-gtk.o divelist-gtk.o planner-gtk.o statistics-gtk.o gtk-gui.o
|
||||
# Add files to the following variables if the auto-detection based on the
|
||||
# filename fails
|
||||
OBJS_NEEDING_MOC =
|
||||
OBJS_NEEDING_UIC =
|
||||
HEADERS_NEEDING_MOC =
|
||||
|
||||
OBJS = main.o dive.o time.o profile.o info.o equipment.o divelist.o deco.o planner.o \
|
||||
parse-xml.o save-xml.o libdivecomputer.o print.o uemis.o uemis-downloader.o \
|
||||
statistics.o file.o device.o download-dialog.o prefs.o \
|
||||
webservice.o sha1.o $(GPSOBJ) $(OSSUPPORT).o $(RESFILE) $(GTKOBJS)
|
||||
|
||||
DEPS = $(wildcard .dep/*.dep)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): gen_version_file $(OBJS) $(MSGOBJS) $(INFOPLIST)
|
||||
@$(PRETTYECHO) ' LINK' $(TARGET)
|
||||
$(COMPILE_PREFIX)$(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
|
||||
|
||||
gen_version_file:
|
||||
ifneq ($(STORED_VERSION_STRING),$(VERSION_STRING))
|
||||
$(info updating $(VERSION_FILE) to $(VERSION_STRING))
|
||||
@echo \#define VERSION_STRING \"$(VERSION_STRING)\" >$(VERSION_FILE)
|
||||
endif
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(BINDIR)
|
||||
$(INSTALL) $(NAME) $(BINDIR)
|
||||
$(INSTALL) -d -m 755 $(DESKTOPDIR)
|
||||
$(INSTALL) $(DESKTOPFILE) $(DESKTOPDIR)
|
||||
$(INSTALL) -d -m 755 $(ICONDIR)
|
||||
$(INSTALL) -m 644 $(ICONFILE) $(ICONDIR)
|
||||
@-if test -z "$(DESTDIR)"; then \
|
||||
$(gtk_update_icon_cache); \
|
||||
fi
|
||||
$(INSTALL) -d -m 755 $(MANDIR)
|
||||
$(INSTALL) -m 644 $(MANFILES) $(MANDIR)
|
||||
@-if test ! -z "$(XSLT)"; then \
|
||||
$(INSTALL) -d -m 755 $(DATADIR)/$(NAME); \
|
||||
$(INSTALL) -d -m 755 $(XSLTDIR); \
|
||||
$(INSTALL) -m 644 $(XSLTFILES) $(XSLTDIR); \
|
||||
fi
|
||||
for LOC in $(wildcard share/locale/*/LC_MESSAGES); do \
|
||||
$(INSTALL) -d $(prefix)/$$LOC; \
|
||||
$(INSTALL) -m 644 $$LOC/$(NAME).mo $(prefix)/$$LOC/$(NAME).mo; \
|
||||
done
|
||||
|
||||
|
||||
install-macosx: all
|
||||
$(INSTALL) -d -m 755 $(MACOSXINSTALL)/Contents/Resources
|
||||
$(INSTALL) -d -m 755 $(MACOSXINSTALL)/Contents/MacOS
|
||||
$(INSTALL) $(NAME) $(MACOSXINSTALL)/Contents/MacOS/$(NAME)-bin
|
||||
$(INSTALL) $(MACOSXFILES)/$(NAME).sh $(MACOSXINSTALL)/Contents/MacOS/$(NAME)
|
||||
$(INSTALL) $(MACOSXFILES)/PkgInfo $(MACOSXINSTALL)/Contents/
|
||||
$(INSTALL) $(MACOSXFILES)/Info.plist $(MACOSXINSTALL)/Contents/
|
||||
$(INSTALL) $(ICONFILE) $(MACOSXINSTALL)/Contents/Resources/
|
||||
$(INSTALL) $(MACOSXFILES)/$(CAPITALIZED_NAME).icns $(MACOSXINSTALL)/Contents/Resources/
|
||||
for LOC in $(wildcard share/locale/*/LC_MESSAGES); do \
|
||||
$(INSTALL) -d -m 755 $(MACOSXINSTALL)/Contents/Resources/$$LOC; \
|
||||
$(INSTALL) $$LOC/$(NAME).mo $(MACOSXINSTALL)/Contents/Resources/$$LOC/$(NAME).mo; \
|
||||
done
|
||||
@-if test ! -z "$(XSLT)"; then \
|
||||
$(INSTALL) -d -m 755 $(MACOSXINSTALL)/Contents/Resources/xslt; \
|
||||
$(INSTALL) -m 644 $(XSLTFILES) $(MACOSXINSTALL)/Contents/Resources/xslt/; \
|
||||
fi
|
||||
|
||||
|
||||
create-macosx-bundle: all
|
||||
$(INSTALL) -d -m 755 $(MACOSXSTAGING)/Contents/Resources
|
||||
$(INSTALL) -d -m 755 $(MACOSXSTAGING)/Contents/MacOS
|
||||
$(INSTALL) $(NAME) $(MACOSXSTAGING)/Contents/MacOS/
|
||||
$(INSTALL) $(MACOSXFILES)/PkgInfo $(MACOSXSTAGING)/Contents/
|
||||
$(INSTALL) $(MACOSXFILES)/Info.plist $(MACOSXSTAGING)/Contents/
|
||||
$(INSTALL) $(ICONFILE) $(MACOSXSTAGING)/Contents/Resources/
|
||||
$(INSTALL) $(MACOSXFILES)/$(CAPITALIZED_NAME).icns $(MACOSXSTAGING)/Contents/Resources/
|
||||
for LOC in $(wildcard share/locale/*/LC_MESSAGES); do \
|
||||
$(INSTALL) -d -m 755 $(MACOSXSTAGING)/Contents/Resources/$$LOC; \
|
||||
$(INSTALL) $$LOC/$(NAME).mo $(MACOSXSTAGING)/Contents/Resources/$$LOC/$(NAME).mo; \
|
||||
done
|
||||
@-if test ! -z "$(XSLT)"; then \
|
||||
$(INSTALL) -d -m 755 $(MACOSXSTAGING)/Contents/Resources/xslt; \
|
||||
$(INSTALL) -m 644 $(XSLTFILES) $(MACOSXSTAGING)/Contents/Resources/xslt/; \
|
||||
fi
|
||||
$(GTK_MAC_BUNDLER) packaging/macosx/$(NAME).bundle
|
||||
|
||||
sign-macosx-bundle: all
|
||||
codesign -s "3A8CE62A483083EDEA5581A61E770EC1FA8BECE8" /Applications/$(CAPITALIZED_NAME).app/Contents/MacOS/$(NAME)-bin
|
||||
|
||||
install-cross-windows: all
|
||||
$(INSTALL) -d -m 755 $(WINDOWSSTAGING)/share/locale
|
||||
for MSG in $(WINMSGDIRS); do\
|
||||
$(INSTALL) -d -m 755 $(WINDOWSSTAGING)/$$MSG;\
|
||||
$(INSTALL) $(CROSS_PATH)/$$MSG/* $(WINDOWSSTAGING)/$$MSG;\
|
||||
done
|
||||
for LOC in $(wildcard share/locale/*/LC_MESSAGES); do \
|
||||
$(INSTALL) -d -m 755 $(WINDOWSSTAGING)/$$LOC; \
|
||||
$(INSTALL) $$LOC/$(NAME).mo $(WINDOWSSTAGING)/$$LOC/$(NAME).mo; \
|
||||
done
|
||||
|
||||
create-windows-installer: all $(NSIFILE) install-cross-windows
|
||||
$(MAKENSIS) $(NSIFILE)
|
||||
|
||||
$(NSIFILE): $(NSIINPUTFILE)
|
||||
$(shell cat $(NSIINPUTFILE) | sed -e 's/VERSIONTOKEN/$(VERSION_STRING)/;s/PRODVTOKEN/$(PRODVERSION_STRING)/' > $(NSIFILE))
|
||||
|
||||
$(INFOPLIST): $(INFOPLISTINPUT)
|
||||
$(shell cat $(INFOPLISTINPUT) | sed -e 's/CFBUNDLEVERSION_TOKEN/$(CFBUNDLEVERSION_STRING)/' > $(INFOPLIST))
|
||||
|
||||
# Transifex merge the translations
|
||||
update-po-files:
|
||||
tx pull -af
|
||||
|
||||
push-pot:
|
||||
xgettext -o po/$(NAME)-new.pot -s -k_ -kN_ --keyword=C_:1c,2 --add-comments="++GETTEXT" *.c
|
||||
tx push -s
|
||||
|
||||
EXTRA_FLAGS = $(GTKCFLAGS) $(GLIB2CFLAGS) $(XML2CFLAGS) \
|
||||
$(XSLT) $(ZIP) $(SQLITE3) $(LIBDIVECOMPUTERCFLAGS) \
|
||||
$(LIBSOUPCFLAGS) $(OSMGPSMAPFLAGS) $(GCONF2CFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
@$(PRETTYECHO) ' CC' $<
|
||||
@mkdir -p .dep
|
||||
$(COMPILE_PREFIX)$(CC) $(CFLAGS) $(EXTRA_FLAGS) -MD -MF .dep/$@.dep -c -o $@ $<
|
||||
|
||||
share/locale/%.UTF-8/LC_MESSAGES/$(NAME).mo: po/%.po po/%.aliases
|
||||
mkdir -p $(dir $@)
|
||||
msgfmt -c -o $@ po/$*.po
|
||||
@-if test -s po/$*.aliases; then \
|
||||
for ALIAS in `cat po/$*.aliases`; do \
|
||||
mkdir -p share/locale/$$ALIAS/LC_MESSAGES; \
|
||||
cp $@ share/locale/$$ALIAS/LC_MESSAGES; \
|
||||
done; \
|
||||
fi
|
||||
|
||||
satellite.png: satellite.svg
|
||||
convert -transparent white -resize 11x16 -depth 8 $< $@
|
||||
|
||||
# This should work, but it doesn't get the colors quite right - so I manually converted with Gimp
|
||||
# convert -colorspace RGB -transparent white -resize 256x256 $(NAME)-icon.svg $(NAME)-icon.png
|
||||
#
|
||||
# The following creates the pixbuf data in .h files with the basename followed by '_pixmap'
|
||||
# as name of the data structure
|
||||
%.h: %.png
|
||||
@$(PRETTYECHO) ' gdk-pixbuf-csource' $<
|
||||
$(COMPILE_PREFIX)gdk-pixbuf-csource --struct --name `echo $* | sed 's/-/_/g'`_pixbuf $< > $@
|
||||
|
||||
doc:
|
||||
$(MAKE) -C Documentation doc
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) *~ $(NAME) $(NAME).exe po/*~ po/$(NAME)-new.pot \
|
||||
$(VERSION_FILE)
|
||||
rm -rf share .dep
|
||||
|
||||
release:
|
||||
@scripts/check-version -cr $(VERSION_STRING)
|
||||
git archive --prefix $(CAPITALIZED_NAME)-$(VERSION_STRING)/ \
|
||||
--output $(CAPITALIZED_NAME)-$(VERSION_STRING).tgz \
|
||||
v$(VERSION_STRING)
|
||||
|
||||
-include $(DEPS)
|
||||
include Rules.mk
|
||||
|
|
252
Rules.mk
Normal file
252
Rules.mk
Normal file
|
@ -0,0 +1,252 @@
|
|||
# -*- Makefile -*-
|
||||
# Rules for building and creating the version file
|
||||
|
||||
VERSION_FILE = version.h
|
||||
# There's only one line in $(VERSION_FILE); use the shell builtin `read'
|
||||
STORED_VERSION_STRING = \
|
||||
$(subst ",,$(shell [ ! -r $(VERSION_FILE) ] || \
|
||||
read ignore ignore v <$(VERSION_FILE) && echo $$v))
|
||||
#" workaround editor syntax highlighting quirk
|
||||
|
||||
GET_VERSION = ./scripts/get-version
|
||||
VERSION_STRING := $(shell $(GET_VERSION) linux || echo "v$(VERSION)")
|
||||
# Mac Info.plist style with three numbers 1.2.3
|
||||
CFBUNDLEVERSION_STRING := $(shell $(GET_VERSION) darwin $(VERSION_STRING) || \
|
||||
echo "$(VERSION).0")
|
||||
# Windows .nsi style with four numbers 1.2.3.4
|
||||
PRODVERSION_STRING := $(shell $(GET_VERSION) win $(VERSION_STRING) || \
|
||||
echo "$(VERSION).0.0")
|
||||
|
||||
MSGOBJS=$(addprefix share/locale/,$(MSGLANGS:.po=.UTF-8/LC_MESSAGES/$(NAME).mo))
|
||||
|
||||
ifeq ($(V),1)
|
||||
PRETTYECHO=true
|
||||
COMPILE_PREFIX=
|
||||
else
|
||||
PRETTYECHO=echo
|
||||
COMPILE_PREFIX=@
|
||||
endif
|
||||
|
||||
C_SOURCES = $(filter %.c, $(SOURCES))
|
||||
CXX_SOURCES = $(filter %.cpp, $(SOURCES)) $(RESOURCES:.qrc=.qrc.cpp)
|
||||
OTHER_SOURCES = $(filter-out %.c %.cpp, $(SOURCES))
|
||||
OBJS = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(OTHER_SOURCES)
|
||||
|
||||
# Add the objects for the header files which define QObject subclasses
|
||||
HEADERS_NEEDING_MOC += $(shell grep -l -s 'Q_OBJECT' $(HEADERS))
|
||||
MOC_OBJS = $(HEADERS_NEEDING_MOC:.h=.moc.o)
|
||||
|
||||
ALL_OBJS = $(OBJS) $(MOC_OBJS)
|
||||
|
||||
# Files for using Qt Creator
|
||||
CREATOR_FILES = $(NAME).config $(NAME).creator $(NAME).files $(NAME).includes
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
$(TARGET): gen_version_file $(ALL_OBJS) $(MSGOBJS) $(INFOPLIST)
|
||||
@$(PRETTYECHO) ' LINK' $(TARGET)
|
||||
$(COMPILE_PREFIX)$(CXX) $(LDFLAGS) -o $(TARGET) $(ALL_OBJS) $(LIBS)
|
||||
|
||||
gen_version_file $(VERSION_FILE):
|
||||
ifneq ($(STORED_VERSION_STRING),$(VERSION_STRING))
|
||||
$(info updating $(VERSION_FILE) to $(VERSION_STRING))
|
||||
@echo \#define VERSION_STRING \"$(VERSION_STRING)\" >$(VERSION_FILE)
|
||||
endif
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(BINDIR)
|
||||
$(INSTALL) $(NAME) $(BINDIR)
|
||||
$(INSTALL) -d -m 755 $(DESKTOPDIR)
|
||||
$(INSTALL) $(DESKTOPFILE) $(DESKTOPDIR)
|
||||
$(INSTALL) -d -m 755 $(ICONDIR)
|
||||
$(INSTALL) -m 644 $(ICONFILE) $(ICONDIR)
|
||||
@-if test -z "$(DESTDIR)"; then \
|
||||
$(gtk_update_icon_cache); \
|
||||
fi
|
||||
$(INSTALL) -d -m 755 $(MANDIR)
|
||||
$(INSTALL) -m 644 $(MANFILES) $(MANDIR)
|
||||
@-if test ! -z "$(XSLT)"; then \
|
||||
$(INSTALL) -d -m 755 $(DATADIR)/$(NAME); \
|
||||
$(INSTALL) -d -m 755 $(XSLTDIR); \
|
||||
$(INSTALL) -m 644 $(XSLTFILES) $(XSLTDIR); \
|
||||
fi
|
||||
for LOC in $(wildcard share/locale/*/LC_MESSAGES); do \
|
||||
$(INSTALL) -d $(prefix)/$$LOC; \
|
||||
$(INSTALL) -m 644 $$LOC/$(NAME).mo $(prefix)/$$LOC/$(NAME).mo; \
|
||||
done
|
||||
|
||||
|
||||
install-macosx: all
|
||||
$(INSTALL) -d -m 755 $(MACOSXINSTALL)/Contents/Resources
|
||||
$(INSTALL) -d -m 755 $(MACOSXINSTALL)/Contents/MacOS
|
||||
$(INSTALL) $(NAME) $(MACOSXINSTALL)/Contents/MacOS/$(NAME)-bin
|
||||
$(INSTALL) $(MACOSXFILES)/$(NAME).sh $(MACOSXINSTALL)/Contents/MacOS/$(NAME)
|
||||
$(INSTALL) $(MACOSXFILES)/PkgInfo $(MACOSXINSTALL)/Contents/
|
||||
$(INSTALL) $(MACOSXFILES)/Info.plist $(MACOSXINSTALL)/Contents/
|
||||
$(INSTALL) $(ICONFILE) $(MACOSXINSTALL)/Contents/Resources/
|
||||
$(INSTALL) $(MACOSXFILES)/$(CAPITALIZED_NAME).icns $(MACOSXINSTALL)/Contents/Resources/
|
||||
for LOC in $(wildcard share/locale/*/LC_MESSAGES); do \
|
||||
$(INSTALL) -d -m 755 $(MACOSXINSTALL)/Contents/Resources/$$LOC; \
|
||||
$(INSTALL) $$LOC/$(NAME).mo $(MACOSXINSTALL)/Contents/Resources/$$LOC/$(NAME).mo; \
|
||||
done
|
||||
@-if test ! -z "$(XSLT)"; then \
|
||||
$(INSTALL) -d -m 755 $(MACOSXINSTALL)/Contents/Resources/xslt; \
|
||||
$(INSTALL) -m 644 $(XSLTFILES) $(MACOSXINSTALL)/Contents/Resources/xslt/; \
|
||||
fi
|
||||
|
||||
|
||||
create-macosx-bundle: all
|
||||
$(INSTALL) -d -m 755 $(MACOSXSTAGING)/Contents/Resources
|
||||
$(INSTALL) -d -m 755 $(MACOSXSTAGING)/Contents/MacOS
|
||||
$(INSTALL) $(NAME) $(MACOSXSTAGING)/Contents/MacOS/
|
||||
$(INSTALL) $(MACOSXFILES)/PkgInfo $(MACOSXSTAGING)/Contents/
|
||||
$(INSTALL) $(MACOSXFILES)/Info.plist $(MACOSXSTAGING)/Contents/
|
||||
$(INSTALL) $(ICONFILE) $(MACOSXSTAGING)/Contents/Resources/
|
||||
$(INSTALL) $(MACOSXFILES)/$(CAPITALIZED_NAME).icns $(MACOSXSTAGING)/Contents/Resources/
|
||||
for LOC in $(wildcard share/locale/*/LC_MESSAGES); do \
|
||||
$(INSTALL) -d -m 755 $(MACOSXSTAGING)/Contents/Resources/$$LOC; \
|
||||
$(INSTALL) $$LOC/$(NAME).mo $(MACOSXSTAGING)/Contents/Resources/$$LOC/$(NAME).mo; \
|
||||
done
|
||||
@-if test ! -z "$(XSLT)"; then \
|
||||
$(INSTALL) -d -m 755 $(MACOSXSTAGING)/Contents/Resources/xslt; \
|
||||
$(INSTALL) -m 644 $(XSLTFILES) $(MACOSXSTAGING)/Contents/Resources/xslt/; \
|
||||
fi
|
||||
$(GTK_MAC_BUNDLER) packaging/macosx/$(NAME).bundle
|
||||
|
||||
sign-macosx-bundle: all
|
||||
codesign -s "3A8CE62A483083EDEA5581A61E770EC1FA8BECE8" /Applications/$(CAPITALIZED_NAME).app/Contents/MacOS/$(NAME)-bin
|
||||
|
||||
install-cross-windows: all
|
||||
$(INSTALL) -d -m 755 $(WINDOWSSTAGING)/share/locale
|
||||
for MSG in $(WINMSGDIRS); do\
|
||||
$(INSTALL) -d -m 755 $(WINDOWSSTAGING)/$$MSG;\
|
||||
$(INSTALL) $(CROSS_PATH)/$$MSG/* $(WINDOWSSTAGING)/$$MSG;\
|
||||
done
|
||||
for LOC in $(wildcard share/locale/*/LC_MESSAGES); do \
|
||||
$(INSTALL) -d -m 755 $(WINDOWSSTAGING)/$$LOC; \
|
||||
$(INSTALL) $$LOC/$(NAME).mo $(WINDOWSSTAGING)/$$LOC/$(NAME).mo; \
|
||||
done
|
||||
|
||||
create-windows-installer: all $(NSIFILE) install-cross-windows
|
||||
$(MAKENSIS) $(NSIFILE)
|
||||
|
||||
$(NSIFILE): $(NSIINPUTFILE)
|
||||
$(shell cat $(NSIINPUTFILE) | sed -e 's/VERSIONTOKEN/$(VERSION_STRING)/;s/PRODVTOKEN/$(PRODVERSION_STRING)/' > $(NSIFILE))
|
||||
|
||||
$(INFOPLIST): $(INFOPLISTINPUT)
|
||||
$(shell cat $(INFOPLISTINPUT) | sed -e 's/CFBUNDLEVERSION_TOKEN/$(CFBUNDLEVERSION_STRING)/' > $(INFOPLIST))
|
||||
|
||||
# Transifex merge the translations
|
||||
update-po-files:
|
||||
xgettext -o po/$(NAME)-new.pot -s -k_ -kN_ -ktr --keyword=C_:1c,2 --add-comments="++GETTEXT" *.c qt-ui/*.cpp
|
||||
tx push -s
|
||||
tx pull -af
|
||||
|
||||
MOCFLAGS = $(filter -I%, $(CXXFLAGS) $(EXTRA_FLAGS)) $(filter -D%, $(CXXFLAGS) $(EXTRA_FLAGS))
|
||||
|
||||
%.o: %.c
|
||||
@$(PRETTYECHO) ' CC' $<
|
||||
@mkdir -p .dep/$(@D)
|
||||
$(COMPILE_PREFIX)$(CC) $(CFLAGS) $(EXTRA_FLAGS) -MD -MF .dep/$@.dep -c -o $@ $<
|
||||
|
||||
%.o: %.cpp
|
||||
@$(PRETTYECHO) ' CXX' $<
|
||||
@mkdir -p .dep/$(@D)
|
||||
$(COMPILE_PREFIX)$(CXX) $(CXXFLAGS) $(EXTRA_FLAGS) -MD -MF .dep/$@.dep -c -o $@ $<
|
||||
|
||||
# This rule is for running the moc on QObject subclasses defined in the .h
|
||||
# files.
|
||||
%.moc.cpp: %.h
|
||||
@$(PRETTYECHO) ' MOC' $<
|
||||
$(COMPILE_PREFIX)$(MOC) $(MOCFLAGS) $< -o $@
|
||||
|
||||
# This rule is for running the moc on QObject subclasses defined in the .cpp
|
||||
# files; remember to #include "<file>.moc" at the end of the .cpp file, or
|
||||
# you'll get linker errors ("undefined vtable for...")
|
||||
%.moc: %.cpp
|
||||
@$(PRETTYECHO) ' MOC' $<
|
||||
$(COMPILE_PREFIX)$(MOC) -i $(MOCFLAGS) $< -o $@
|
||||
|
||||
# This creates the Qt resource sources.
|
||||
%.qrc.cpp: %.qrc
|
||||
@$(PRETTYECHO) ' RCC' $<
|
||||
$(COMPILE_PREFIX)$(RCC) $< -o $@
|
||||
%.qrc:
|
||||
|
||||
# This creates the ui headers.
|
||||
ui_%.h: %.ui
|
||||
@$(PRETTYECHO) ' UIC' $<
|
||||
$(COMPILE_PREFIX)$(UIC) $< -o $@
|
||||
|
||||
# This forces the creation of ui headers with the wrong path
|
||||
# This is required because the -MG option to the compiler outputs
|
||||
# unknown files with no path prefix
|
||||
ui_%.h: qt-ui/%.ui
|
||||
@$(PRETTYECHO) ' UIC' $<
|
||||
$(COMPILE_PREFIX)$(UIC) $< -o qt-ui/$@
|
||||
|
||||
share/locale/%.UTF-8/LC_MESSAGES/$(NAME).mo: po/%.po po/%.aliases
|
||||
@$(PRETTYECHO) ' MSGFMT' $*.po
|
||||
@mkdir -p $(dir $@)
|
||||
$(COMPILE_PREFIX)msgfmt -c -o $@ po/$*.po
|
||||
@-if test -s po/$*.aliases; then \
|
||||
for ALIAS in `cat po/$*.aliases`; do \
|
||||
mkdir -p share/locale/$$ALIAS/LC_MESSAGES; \
|
||||
cp $@ share/locale/$$ALIAS/LC_MESSAGES; \
|
||||
done; \
|
||||
fi
|
||||
|
||||
satellite.png: satellite.svg
|
||||
convert -transparent white -resize 11x16 -depth 8 $< $@
|
||||
|
||||
# This should work, but it doesn't get the colors quite right - so I manually converted with Gimp
|
||||
# convert -colorspace RGB -transparent white -resize 256x256 subsurface-icon.svg subsurface-icon.png
|
||||
#
|
||||
# The following creates the pixbuf data in .h files with the basename followed by '_pixmap'
|
||||
# as name of the data structure
|
||||
%.h: %.png
|
||||
@echo ' gdk-pixbuf-csource' $<
|
||||
@gdk-pixbuf-csource --struct --name `echo $* | sed 's/-/_/g'`_pixbuf $< > $@
|
||||
|
||||
doc:
|
||||
$(MAKE) -C Documentation doc
|
||||
|
||||
clean:
|
||||
rm -f $(ALL_OBJS) *~ $(NAME) $(NAME).exe po/*~ po/$(NAME)-new.pot \
|
||||
$(VERSION_FILE) $(HEADERS_NEEDING_MOC:.h=.moc) *.moc qt-ui/*.moc qt-ui/ui_*.h
|
||||
rm -f $(RESOURCES:.qrc=.qrc.cpp)
|
||||
rm -rf share
|
||||
|
||||
confclean: clean
|
||||
rm -f $(CONFIGFILE)
|
||||
rm -rf .dep
|
||||
|
||||
distclean: confclean
|
||||
rm -f $(CREATOR_FILES)
|
||||
|
||||
release:
|
||||
@scripts/check-version -cr $(VERSION_STRING)
|
||||
git archive --prefix $(CAPITALIZED_NAME)-$(VERSION_STRING)/ \
|
||||
--output $(CAPITALIZED_NAME)-$(VERSION_STRING).tgz \
|
||||
v$(VERSION_STRING)
|
||||
|
||||
.PHONY: creator-files
|
||||
creator-files: $(CREATOR_FILES)
|
||||
$(NAME).files: Makefile $(CONFIGFILE)
|
||||
echo $(wildcard *.h) $(HEADERS) $(SOURCES) | tr ' ' '\n' | sort | uniq > $(NAME).files
|
||||
$(NAME).config: Makefile $(CONFIGFILE)
|
||||
echo $(patsubst -D%,%,$(filter -D%, $(CXXFLAGS) $(CFLAGS) $(EXTRA_FLAGS))) | tr ' ' '\n' | sort | uniq > $(NAME).config
|
||||
$(NAME).includes: Makefile $(CONFIGFILE)
|
||||
echo $$PWD > $(NAME).includes
|
||||
echo $(patsubst -I%,%,$(filter -I%, $(CXXFLAGS) $(CFLAGS) $(EXTRA_FLAGS))) | tr ' ' '\n' | sort | uniq >> $(NAME).includes
|
||||
$(NAME).creator:
|
||||
echo '[General]' > $(NAME).creator
|
||||
|
||||
ifneq ($(CONFIGURED)$(CONFIGURING),)
|
||||
.dep/%.o.dep: %.cpp
|
||||
@mkdir -p $(@D)
|
||||
@$(CXX) $(CXXFLAGS) $(EXTRA_FLAGS) -MM -MG -MF $@ -MT $(<:.cpp=.o) -c $<
|
||||
endif
|
||||
|
||||
DEPS = $(addprefix .dep/,$(C_SOURCES:.c=.o.dep) $(CXX_SOURCES:.cpp=.o.dep))
|
||||
-include $(DEPS)
|
|
@ -9,7 +9,7 @@ static void name(GtkWidget *w, gpointer data) \
|
|||
#define OPTIONCALLBACK(name, option) \
|
||||
static void name(GtkWidget *w, gpointer data) \
|
||||
{ \
|
||||
GtkWidget **entry = data; \
|
||||
GtkWidget **entry = (GtkWidget**)data; \
|
||||
option = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)); \
|
||||
update_screen(); \
|
||||
if (entry) \
|
||||
|
|
80
color.h
80
color.h
|
@ -4,54 +4,56 @@
|
|||
/* The colors are named by picking the closest match
|
||||
from http://chir.ag/projects/name-that-color */
|
||||
|
||||
#include <QColor>
|
||||
|
||||
// Greens
|
||||
#define CAMARONE1 { 0.0, 0.4, 0.0, 1 }
|
||||
#define FUNGREEN1 { 0.0, 0.4, 0.2, 1 }
|
||||
#define FUNGREEN1_HIGH_TRANS { 0.0, 0.4, 0.2, 0.25 }
|
||||
#define KILLARNEY1 { 0.2, 0.4, 0.2, 1 }
|
||||
#define APPLE1 { 0.2, 0.6, 0.2, 1 }
|
||||
#define APPLE1_MED_TRANS { 0.2, 0.6, 0.2, 0.5 }
|
||||
#define APPLE1_HIGH_TRANS { 0.2, 0.6, 0.2, 0.25 }
|
||||
#define LIMENADE1 { 0.4, 0.8, 0.0, 1 }
|
||||
#define ATLANTIS1 { 0.4, 0.8, 0.2, 1 }
|
||||
#define ATLANTIS2 { 0.6, 0.8, 0.2, 1 }
|
||||
#define RIOGRANDE1 { 0.8, 0.8, 0.0, 1 }
|
||||
#define EARLSGREEN1 { 0.8, 0.8, 0.2, 1 }
|
||||
#define FORESTGREEN1 { 0.1, 0.5, 0.1, 1 }
|
||||
#define CAMARONE1 QColor::fromRgbF( 0.0, 0.4, 0.0, 1 )
|
||||
#define FUNGREEN1 QColor::fromRgbF( 0.0, 0.4, 0.2, 1 )
|
||||
#define FUNGREEN1_HIGH_TRANS QColor::fromRgbF( 0.0, 0.4, 0.2, 0.25 )
|
||||
#define KILLARNEY1 QColor::fromRgbF( 0.2, 0.4, 0.2, 1 )
|
||||
#define APPLE1 QColor::fromRgbF( 0.2, 0.6, 0.2, 1 )
|
||||
#define APPLE1_MED_TRANS QColor::fromRgbF( 0.2, 0.6, 0.2, 0.5 )
|
||||
#define APPLE1_HIGH_TRANS QColor::fromRgbF( 0.2, 0.6, 0.2, 0.25 )
|
||||
#define LIMENADE1 QColor::fromRgbF( 0.4, 0.8, 0.0, 1 )
|
||||
#define ATLANTIS1 QColor::fromRgbF( 0.4, 0.8, 0.2, 1 )
|
||||
#define ATLANTIS2 QColor::fromRgbF( 0.6, 0.8, 0.2, 1 )
|
||||
#define RIOGRANDE1 QColor::fromRgbF( 0.8, 0.8, 0.0, 1 )
|
||||
#define EARLSGREEN1 QColor::fromRgbF( 0.8, 0.8, 0.2, 1 )
|
||||
#define FORESTGREEN1 QColor::fromRgbF( 0.1, 0.5, 0.1, 1 )
|
||||
|
||||
// Reds
|
||||
#define PERSIANRED1 { 0.8, 0.2, 0.2, 1 }
|
||||
#define TUSCANY1 { 0.8, 0.4, 0.2, 1 }
|
||||
#define PIRATEGOLD1 { 0.8, 0.5, 0.0, 1 }
|
||||
#define HOKEYPOKEY1 { 0.8, 0.6, 0.2, 1 }
|
||||
#define CINNABAR1 { 0.9, 0.3, 0.2, 1 }
|
||||
#define REDORANGE1 { 1.0, 0.2, 0.2, 1 }
|
||||
#define REDORANGE1_HIGH_TRANS { 1.0, 0.2, 0.2, 0.25 }
|
||||
#define REDORANGE1_MED_TRANS { 1.0, 0.2, 0.2, 0.5 }
|
||||
#define RED1_MED_TRANS { 1.0, 0.0, 0.0, 0.5 }
|
||||
#define RED1 { 1.0, 0.0, 0.0, 1 }
|
||||
#define PERSIANRED1 QColor::fromRgbF( 0.8, 0.2, 0.2, 1 )
|
||||
#define TUSCANY1 QColor::fromRgbF( 0.8, 0.4, 0.2, 1 )
|
||||
#define PIRATEGOLD1 QColor::fromRgbF( 0.8, 0.5, 0.0, 1 )
|
||||
#define HOKEYPOKEY1 QColor::fromRgbF( 0.8, 0.6, 0.2, 1 )
|
||||
#define CINNABAR1 QColor::fromRgbF( 0.9, 0.3, 0.2, 1 )
|
||||
#define REDORANGE1 QColor::fromRgbF( 1.0, 0.2, 0.2, 1 )
|
||||
#define REDORANGE1_HIGH_TRANS QColor::fromRgbF( 1.0, 0.2, 0.2, 0.25 )
|
||||
#define REDORANGE1_MED_TRANS QColor::fromRgbF( 1.0, 0.2, 0.2, 0.5 )
|
||||
#define RED1_MED_TRANS QColor::fromRgbF( 1.0, 0.0, 0.0, 0.5 )
|
||||
#define RED1 QColor::fromRgbF( 1.0, 0.0, 0.0, 1 )
|
||||
|
||||
// Monochromes
|
||||
#define BLACK1_LOW_TRANS { 0.0, 0.0, 0.0, 0.75 }
|
||||
#define BLACK1_HIGH_TRANS { 0.0, 0.0, 0.0, 0.25 }
|
||||
#define TUNDORA1_MED_TRANS { 0.3, 0.3, 0.3, 0.5 }
|
||||
#define MERCURY1_MED_TRANS { 0.9, 0.9, 0.9, 0.5 }
|
||||
#define CONCRETE1_LOWER_TRANS { 0.95, 0.95, 0.95, 0.9 }
|
||||
#define WHITE1_MED_TRANS { 1.0, 1.0, 1.0, 0.5 }
|
||||
#define WHITE1 { 1.0, 1.0, 1.0, 1 }
|
||||
#define BLACK1_LOW_TRANS QColor::fromRgbF( 0.0, 0.0, 0.0, 0.75 )
|
||||
#define BLACK1_HIGH_TRANS QColor::fromRgbF( 0.0, 0.0, 0.0, 0.25 )
|
||||
#define TUNDORA1_MED_TRANS QColor::fromRgbF( 0.3, 0.3, 0.3, 0.5 )
|
||||
#define MERCURY1_MED_TRANS QColor::fromRgbF( 0.9, 0.9, 0.9, 0.5 )
|
||||
#define CONCRETE1_LOWER_TRANS QColor::fromRgbF( 0.95, 0.95, 0.95, 0.9 )
|
||||
#define WHITE1_MED_TRANS QColor::fromRgbF( 1.0, 1.0, 1.0, 0.5 )
|
||||
#define WHITE1 QColor::fromRgbF( 1.0, 1.0, 1.0, 1 )
|
||||
|
||||
// Blues
|
||||
#define GOVERNORBAY2 { 0.2, 0.2, 0.7, 1 }
|
||||
#define GOVERNORBAY1_MED_TRANS { 0.2, 0.2, 0.8, 0.5 }
|
||||
#define ROYALBLUE2 { 0.2, 0.2, 0.9, 1 }
|
||||
#define ROYALBLUE2_LOW_TRANS { 0.2, 0.2, 0.9, 0.75 }
|
||||
#define GOVERNORBAY2 QColor::fromRgbF( 0.2, 0.2, 0.7, 1 )
|
||||
#define GOVERNORBAY1_MED_TRANS QColor::fromRgbF( 0.2, 0.2, 0.8, 0.5 )
|
||||
#define ROYALBLUE2 QColor::fromRgbF( 0.2, 0.2, 0.9, 1 )
|
||||
#define ROYALBLUE2_LOW_TRANS QColor::fromRgbF( 0.2, 0.2, 0.9, 0.75 )
|
||||
|
||||
// Yellows / BROWNS
|
||||
#define SPRINGWOOD1 { 0.95, 0.95, 0.9, 1 }
|
||||
#define BROOM1_LOWER_TRANS { 1.0, 1.0, 0.1, 0.9 }
|
||||
#define PEANUT { 0.5, 0.2, 0.1, 1.0 }
|
||||
#define PEANUT_MED_TRANS { 0.5, 0.2, 0.1, 0.5 }
|
||||
#define SPRINGWOOD1 QColor::fromRgbF( 0.95, 0.95, 0.9, 1 )
|
||||
#define BROOM1_LOWER_TRANS QColor::fromRgbF( 1.0, 1.0, 0.1, 0.9 )
|
||||
#define PEANUT QColor::fromRgbF( 0.5, 0.2, 0.1, 1.0 )
|
||||
#define PEANUT_MED_TRANS QColor::fromRgbF( 0.5, 0.2, 0.1, 0.5 )
|
||||
// Magentas
|
||||
#define MEDIUMREDVIOLET1_HIGHER_TRANS { 0.7, 0.2, 0.7, 0.1 }
|
||||
#define MEDIUMREDVIOLET1_HIGHER_TRANS QColor::fromRgbF( 0.7, 0.2, 0.7, 0.1 )
|
||||
|
||||
#endif
|
||||
|
|
16
conversions.h
Normal file
16
conversions.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* conversions.h
|
||||
*
|
||||
* Helpers to convert between different units
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void convert_volume_pressure(int ml, int mbar, double *v, double *p);
|
||||
int convert_pressure(int mbar, double *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
8
device.h
8
device.h
|
@ -1,6 +1,10 @@
|
|||
#ifndef DEVICE_INFO_H
|
||||
#define DEVICE_INFO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct device_info {
|
||||
const char *model;
|
||||
uint32_t deviceid;
|
||||
|
@ -17,4 +21,8 @@ extern struct device_info *create_device_info(const char *model, uint32_t device
|
|||
extern struct device_info *remove_device_info(const char *model, uint32_t deviceid);
|
||||
extern struct device_info *head_of_device_info_list(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include <gdk/gdkkeysyms-compat.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern GtkWidget *main_window;
|
||||
|
||||
/* we want a progress bar as part of the device_data_t - let's abstract this out */
|
||||
|
@ -35,15 +39,11 @@ extern void set_divelist_font(const char *);
|
|||
|
||||
extern void update_screen(void);
|
||||
extern void download_dialog(GtkWidget *, gpointer);
|
||||
extern int is_default_dive_computer_device(const char *);
|
||||
extern int is_default_dive_computer(const char *, const char *);
|
||||
|
||||
extern void add_dive_cb(GtkWidget *, gpointer);
|
||||
extern void update_progressbar(progressbar_t *progress, double value);
|
||||
extern void update_progressbar_text(progressbar_t *progress, const char *text);
|
||||
|
||||
extern const char *default_dive_computer_vendor;
|
||||
extern const char *default_dive_computer_product;
|
||||
extern const char *default_dive_computer_device;
|
||||
|
||||
// info.c
|
||||
enum {
|
||||
|
@ -90,22 +90,6 @@ typedef gint (*sort_func_t)(GtkTreeModel *model,
|
|||
GtkTreeIter *b,
|
||||
gpointer user_data);
|
||||
|
||||
#define ALIGN_LEFT 1
|
||||
#define ALIGN_RIGHT 2
|
||||
#define INVISIBLE 4
|
||||
#define UNSORTABLE 8
|
||||
#define EDITABLE 16
|
||||
|
||||
#ifndef TEXT_SCALE
|
||||
#define TEXT_SCALE 1.0
|
||||
#endif
|
||||
|
||||
#define DEPTH_TEXT_SIZE (10 * TEXT_SCALE)
|
||||
#define PRESSURE_TEXT_SIZE (10 * TEXT_SCALE)
|
||||
#define DC_TEXT_SIZE (10.5 * TEXT_SCALE)
|
||||
#define PP_TEXT_SIZE (11 * TEXT_SCALE)
|
||||
#define TEMP_TEXT_SIZE (12 * TEXT_SCALE)
|
||||
|
||||
extern GtkTreeViewColumn *tree_view_column(GtkWidget *tree_view, int index, const char *title,
|
||||
data_func_t data_func, unsigned int flags);
|
||||
extern GtkTreeViewColumn *tree_view_column_add_pixbuf(GtkWidget *tree_view, data_func_t data_func, GtkTreeViewColumn *col);
|
||||
|
@ -115,4 +99,8 @@ GError *uemis_download(const char *path, progressbar_t *progress, GtkDialog *dia
|
|||
/* from planner.c */
|
||||
extern void input_plan(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
31
display.h
31
display.h
|
@ -1,14 +1,18 @@
|
|||
#ifndef DISPLAY_H
|
||||
#define DISPLAY_H
|
||||
|
||||
#include <cairo.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SCALE_SCREEN 1.0
|
||||
#define SCALE_PRINT (1.0 / get_screen_dpi())
|
||||
|
||||
extern void repaint_dive(void);
|
||||
extern void do_print(void);
|
||||
extern gdouble get_screen_dpi(void);
|
||||
|
||||
// Commented out because I don't know how to get the dpi on a paint device yet.
|
||||
extern double get_screen_dpi(void);
|
||||
|
||||
/* Plot info with smoothing, velocity indication
|
||||
* and one-, two- and three-minute minimums and maximums */
|
||||
|
@ -20,10 +24,15 @@ struct plot_info {
|
|||
int mintemp, maxtemp;
|
||||
double endtempcoord;
|
||||
double maxpp;
|
||||
gboolean has_ndl;
|
||||
bool has_ndl;
|
||||
struct plot_data *entry;
|
||||
};
|
||||
|
||||
/*
|
||||
// I'm not sure if this is needed anymore - but keeping this here
|
||||
// so I wont break stuff trying to redo the well.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Cairo scaling really is horribly horribly mis-designed.
|
||||
*
|
||||
|
@ -34,8 +43,6 @@ struct plot_info {
|
|||
*/
|
||||
struct graphics_context {
|
||||
int printer;
|
||||
cairo_t *cr;
|
||||
cairo_rectangle_t drawing_area;
|
||||
double maxx, maxy;
|
||||
double leftx, rightx;
|
||||
double topy, bottomy;
|
||||
|
@ -49,7 +56,7 @@ extern void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t sc
|
|||
extern struct divecomputer *select_dc(struct divecomputer *main);
|
||||
extern void init_profile_background(struct graphics_context *gc);
|
||||
extern void attach_tooltip(int x, int y, int w, int h, const char *text, struct event *event);
|
||||
extern void get_plot_details(struct graphics_context *gc, int time, char *buf, size_t bufsize);
|
||||
extern void get_plot_details(struct graphics_context *gc, int time, char *buf, int bufsize);
|
||||
extern int x_to_time(double x);
|
||||
extern int x_abs(double x);
|
||||
|
||||
|
@ -57,7 +64,7 @@ struct options {
|
|||
enum { PRETTY, TABLE, TWOPERPAGE } type;
|
||||
int print_selected;
|
||||
int color_selected;
|
||||
gboolean notes_up;
|
||||
bool notes_up;
|
||||
int profile_height, notes_height, tanks_height;
|
||||
};
|
||||
|
||||
|
@ -65,4 +72,14 @@ extern char zoomed_plot, dc_number;
|
|||
|
||||
extern unsigned int amount_selected;
|
||||
|
||||
extern int is_default_dive_computer_device(const char *);
|
||||
extern int is_default_dive_computer(const char *, const char *);
|
||||
extern const char *default_dive_computer_vendor;
|
||||
extern const char *default_dive_computer_product;
|
||||
extern const char *default_dive_computer_device;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
9
dive.c
9
dive.c
|
@ -1810,6 +1810,15 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean pr
|
|||
return res;
|
||||
}
|
||||
|
||||
int get_index_for_dive(struct dive *dive) {
|
||||
int i;
|
||||
struct dive *d;
|
||||
for_each_dive(i, d)
|
||||
if (d == dive)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct dive *find_dive_including(timestamp_t when)
|
||||
{
|
||||
int i;
|
||||
|
|
33
dive.h
33
dive.h
|
@ -13,6 +13,16 @@
|
|||
|
||||
#include "sha1.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#else
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
typedef int bool;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define O2_IN_AIR 209 // permille
|
||||
#define N2_IN_AIR 781
|
||||
#define O2_DENSITY 1429 // mg/Liter
|
||||
|
@ -372,6 +382,8 @@ struct dive {
|
|||
struct divecomputer dc;
|
||||
};
|
||||
|
||||
extern int get_index_for_dive(struct dive *dive);
|
||||
|
||||
static inline int dive_has_gps_location(struct dive *dive)
|
||||
{
|
||||
return dive->latitude.udeg || dive->longitude.udeg;
|
||||
|
@ -549,7 +561,7 @@ static inline struct divecomputer *get_dive_dc(struct dive *dive, int nr)
|
|||
#define for_each_gps_location(_i,_x) \
|
||||
for ((_i) = 0; ((_x) = get_gps_location(_i, &gps_location_table)) != NULL; (_i)++)
|
||||
|
||||
static inline struct dive *get_dive_by_diveid(int diveid, int deviceid)
|
||||
static inline struct dive *get_dive_by_diveid(uint32_t diveid, uint32_t deviceid)
|
||||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
|
@ -609,7 +621,6 @@ extern struct sample *prepare_sample(struct divecomputer *dc);
|
|||
extern void finish_sample(struct divecomputer *dc);
|
||||
|
||||
extern void sort_table(struct dive_table *table);
|
||||
extern void report_dives(gboolean imported, gboolean prefer_imported);
|
||||
extern struct dive *fixup_dive(struct dive *dive);
|
||||
extern unsigned int dc_airtemp(struct divecomputer *dc);
|
||||
extern struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean prefer_downloaded);
|
||||
|
@ -622,6 +633,7 @@ extern void add_event(struct divecomputer *dc, int time, int type, int flags, in
|
|||
/* UI related protopypes */
|
||||
|
||||
extern void init_ui(int *argcp, char ***argvp);
|
||||
extern void init_qt_ui(int *argcp, char ***argvp);
|
||||
|
||||
extern void run_ui(void);
|
||||
extern void exit_ui(void);
|
||||
|
@ -717,11 +729,28 @@ void get_gas_string(int o2, int he, char *buf, int len);
|
|||
|
||||
struct event *get_next_event(struct event *event, char *name);
|
||||
|
||||
|
||||
/* this struct holds the information that
|
||||
* describes the cylinders of air.
|
||||
* it is a global variable initialized in equipment.c
|
||||
* used to fill the combobox in the add/edit cylinder
|
||||
* dialog
|
||||
*/
|
||||
|
||||
struct tank_info {
|
||||
const char *name;
|
||||
int cuft, ml, psi, bar;
|
||||
};
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
extern char *debugfilename;
|
||||
extern FILE *debugfile;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "pref.h"
|
||||
|
||||
#endif /* DIVE_H */
|
||||
|
|
|
@ -55,7 +55,6 @@ static struct DiveList dive_list;
|
|||
#define TREESTORE(_dl) GTK_TREE_STORE((_dl).treemodel)
|
||||
#define LISTSTORE(_dl) GTK_TREE_STORE((_dl).listmodel)
|
||||
|
||||
short autogroup = FALSE;
|
||||
static gboolean ignore_selection_changes = FALSE;
|
||||
static gboolean in_set_cursor = FALSE;
|
||||
static gboolean set_selected(GtkTreeModel *model, GtkTreePath *path,
|
||||
|
@ -255,7 +254,6 @@ static void date_data_func(GtkTreeViewColumn *col,
|
|||
gpointer data)
|
||||
{
|
||||
int idx, nr;
|
||||
struct tm tm;
|
||||
timestamp_t when;
|
||||
/* this should be enought for most languages. if not increase the value. */
|
||||
char *buffer;
|
||||
|
@ -263,11 +261,10 @@ static void date_data_func(GtkTreeViewColumn *col,
|
|||
gtk_tree_model_get(model, iter, DIVE_INDEX, &idx, DIVE_DATE, &when, -1);
|
||||
nr = gtk_tree_model_iter_n_children(model, iter);
|
||||
|
||||
utc_mkdate(when, &tm);
|
||||
if (idx < 0) {
|
||||
buffer = get_trip_date_string(&tm, nr);
|
||||
buffer = get_trip_date_string(when, nr);
|
||||
} else {
|
||||
buffer = get_dive_date_string(&tm);
|
||||
buffer = get_dive_date_string(when);
|
||||
}
|
||||
g_object_set(renderer, "text", buffer, NULL);
|
||||
free(buffer);
|
||||
|
@ -430,40 +427,24 @@ static gint nitrox_sort_func(GtkTreeModel *model,
|
|||
return a_he - b_he;
|
||||
}
|
||||
|
||||
#define UTF8_ELLIPSIS "\xE2\x80\xA6"
|
||||
|
||||
static void nitrox_data_func(GtkTreeViewColumn *col,
|
||||
GtkCellRenderer *renderer,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
int idx, o2, he, o2low;
|
||||
char buffer[80];
|
||||
int idx;
|
||||
char *buffer;
|
||||
struct dive *dive;
|
||||
|
||||
gtk_tree_model_get(model, iter, DIVE_INDEX, &idx, -1);
|
||||
if (idx < 0) {
|
||||
*buffer = '\0';
|
||||
goto exit;
|
||||
if (idx >= 0 && (dive = get_dive(idx))) {
|
||||
buffer = get_nitrox_string(dive);
|
||||
g_object_set(renderer, "text", buffer, NULL);
|
||||
free(buffer);
|
||||
} else {
|
||||
g_object_set(renderer, "text", "", NULL);
|
||||
}
|
||||
dive = get_dive(idx);
|
||||
get_dive_gas(dive, &o2, &he, &o2low);
|
||||
o2 = (o2 + 5) / 10;
|
||||
he = (he + 5) / 10;
|
||||
o2low = (o2low + 5) / 10;
|
||||
|
||||
if (he)
|
||||
snprintf(buffer, sizeof(buffer), "%d/%d", o2, he);
|
||||
else if (o2)
|
||||
if (o2 == o2low)
|
||||
snprintf(buffer, sizeof(buffer), "%d", o2);
|
||||
else
|
||||
snprintf(buffer, sizeof(buffer), "%d" UTF8_ELLIPSIS "%d", o2low, o2);
|
||||
else
|
||||
strcpy(buffer, _("air"));
|
||||
exit:
|
||||
g_object_set(renderer, "text", buffer, NULL);
|
||||
}
|
||||
|
||||
/* Render the SAC data (integer value of "ml / min") */
|
||||
|
@ -804,7 +785,6 @@ static gint gtk_dive_nr_sort(GtkTreeModel *model,
|
|||
return dive_nr_sort(idx_a, idx_b, when_a, when_b);
|
||||
}
|
||||
|
||||
|
||||
static struct divelist_column {
|
||||
const char *header;
|
||||
data_func_t data;
|
||||
|
@ -898,6 +878,12 @@ static void row_activated_cb(GtkTreeView *tree_view,
|
|||
edit_dive_info(get_dive(index), FALSE);
|
||||
}
|
||||
|
||||
void report_dives(bool is_imported, bool prefer_imported)
|
||||
{
|
||||
process_dives(is_imported, prefer_imported);
|
||||
dive_list_update_dives();
|
||||
}
|
||||
|
||||
void add_dive_cb(GtkWidget *menuitem, gpointer data)
|
||||
{
|
||||
struct dive *dive;
|
||||
|
|
200
divelist.c
200
divelist.c
|
@ -50,6 +50,8 @@
|
|||
|
||||
static short dive_list_changed = FALSE;
|
||||
|
||||
short autogroup = FALSE;
|
||||
|
||||
dive_trip_t *dive_trip_list;
|
||||
|
||||
unsigned int amount_selected;
|
||||
|
@ -69,6 +71,13 @@ void dump_selection(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
void set_autogroup(gboolean value)
|
||||
{
|
||||
/* if we keep the UI paradigm, this needs to toggle
|
||||
* the checkbox on the autogroup menu item */
|
||||
autogroup = value;
|
||||
}
|
||||
|
||||
dive_trip_t *find_trip_by_idx(int idx)
|
||||
{
|
||||
dive_trip_t *trip = dive_trip_list;
|
||||
|
@ -131,7 +140,7 @@ int trip_has_selected_dives(dive_trip_t *trip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Get the values as we want to show them. Whole feet. But meters with one decimal for
|
||||
/* Get the values as we want to show them. Whole feet. But meters with one decimal for
|
||||
* values less than 20m, without decimals for larger values */
|
||||
void get_depth_values(int depth, int *depth_int, int *depth_decimal, int *show_decimal)
|
||||
{
|
||||
|
@ -557,38 +566,71 @@ void get_suit(struct dive *dive, char **str)
|
|||
|
||||
#define MAX_DATE_STRING 256
|
||||
/* caller needs to free the string */
|
||||
char *get_dive_date_string(struct tm *tm) {
|
||||
char *get_dive_date_string(timestamp_t when) {
|
||||
char *buffer = malloc(MAX_DATE_STRING);
|
||||
if (buffer)
|
||||
if (buffer) {
|
||||
struct tm tm;
|
||||
utc_mkdate(when, &tm);
|
||||
snprintf(buffer, MAX_DATE_STRING,
|
||||
/*++GETTEXT 60 char buffer weekday, monthname, day of month, year, hour:min */
|
||||
_("%1$s, %2$s %3$d, %4$d %5$02d:%6$02d"),
|
||||
weekday(tm->tm_wday),
|
||||
monthname(tm->tm_mon),
|
||||
tm->tm_mday, tm->tm_year + 1900,
|
||||
tm->tm_hour, tm->tm_min);
|
||||
weekday(tm.tm_wday),
|
||||
monthname(tm.tm_mon),
|
||||
tm.tm_mday, tm.tm_year + 1900,
|
||||
tm.tm_hour, tm.tm_min);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* caller needs to free the string */
|
||||
char *get_trip_date_string(struct tm *tm, int nr) {
|
||||
char *get_trip_date_string(timestamp_t when, int nr) {
|
||||
char *buffer = malloc(MAX_DATE_STRING);
|
||||
if (buffer)
|
||||
if (buffer) {
|
||||
struct tm tm;
|
||||
utc_mkdate(when, &tm);
|
||||
snprintf(buffer, MAX_DATE_STRING,
|
||||
/*++GETTEXT 60 char buffer weekday, monthname, day of month, year, nr dives */
|
||||
ngettext("Trip %1$s, %2$s %3$d, %4$d (%5$d dive)",
|
||||
"Trip %1$s, %2$s %3$d, %4$d (%5$d dives)", nr),
|
||||
weekday(tm->tm_wday),
|
||||
monthname(tm->tm_mon),
|
||||
tm->tm_mday, tm->tm_year + 1900,
|
||||
weekday(tm.tm_wday),
|
||||
monthname(tm.tm_mon),
|
||||
tm.tm_mday, tm.tm_year + 1900,
|
||||
nr);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#define MAX_NITROX_STRING 80
|
||||
#define UTF8_ELLIPSIS "\xE2\x80\xA6"
|
||||
|
||||
/* callers needs to free the string */
|
||||
char *get_nitrox_string(struct dive *dive)
|
||||
{
|
||||
int o2, he, o2low;
|
||||
char *buffer = malloc(MAX_NITROX_STRING);
|
||||
|
||||
if (buffer) {
|
||||
get_dive_gas(dive, &o2, &he, &o2low);
|
||||
o2 = (o2 + 5) / 10;
|
||||
he = (he + 5) / 10;
|
||||
o2low = (o2low + 5) / 10;
|
||||
|
||||
if (he)
|
||||
snprintf(buffer, MAX_NITROX_STRING, "%d/%d", o2, he);
|
||||
else if (o2)
|
||||
if (o2 == o2low)
|
||||
snprintf(buffer, MAX_NITROX_STRING, "%d", o2);
|
||||
else
|
||||
snprintf(buffer, MAX_NITROX_STRING, "%d" UTF8_ELLIPSIS "%d", o2low, o2);
|
||||
else
|
||||
strcpy(buffer, _("air"));
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* helper functions for dive_trip handling
|
||||
*/
|
||||
|
||||
#ifdef DEBUG_TRIP
|
||||
void dump_trip_list(void)
|
||||
{
|
||||
|
@ -869,20 +911,23 @@ void merge_dive_index(int i, struct dive *a)
|
|||
add_single_dive(i, res);
|
||||
delete_single_dive(i+1);
|
||||
delete_single_dive(i+1);
|
||||
|
||||
#if USE_GTK_UI
|
||||
dive_list_update_dives();
|
||||
#endif
|
||||
mark_divelist_changed(TRUE);
|
||||
}
|
||||
|
||||
void select_dive(int idx)
|
||||
{
|
||||
struct dive *dive = get_dive(idx);
|
||||
if (dive && !dive->selected) {
|
||||
if (dive) {
|
||||
/* never select an invalid dive that isn't displayed */
|
||||
if (dive->dive_tags & DTAG_INVALID && !prefs.display_invalid_dives)
|
||||
return;
|
||||
dive->selected = 1;
|
||||
amount_selected++;
|
||||
if (!dive->selected) {
|
||||
dive->selected = 1;
|
||||
amount_selected++;
|
||||
}
|
||||
selected_dive = idx;
|
||||
}
|
||||
}
|
||||
|
@ -935,3 +980,124 @@ void remove_autogen_trips()
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When adding dives to the dive table, we try to renumber
|
||||
* the new dives based on any old dives in the dive table.
|
||||
*
|
||||
* But we only do it if:
|
||||
*
|
||||
* - there are no dives in the dive table
|
||||
*
|
||||
* OR
|
||||
*
|
||||
* - the last dive in the old dive table was numbered
|
||||
*
|
||||
* - all the new dives are strictly at the end (so the
|
||||
* "last dive" is at the same location in the dive table
|
||||
* after re-sorting the dives.
|
||||
*
|
||||
* - none of the new dives have any numbers
|
||||
*
|
||||
* This catches the common case of importing new dives from
|
||||
* a dive computer, and gives them proper numbers based on
|
||||
* your old dive list. But it tries to be very conservative
|
||||
* and not give numbers if there is *any* question about
|
||||
* what the numbers should be - in which case you need to do
|
||||
* a manual re-numbering.
|
||||
*/
|
||||
static void try_to_renumber(struct dive *last, int preexisting)
|
||||
{
|
||||
int i, nr;
|
||||
|
||||
/*
|
||||
* If the new dives aren't all strictly at the end,
|
||||
* we're going to expect the user to do a manual
|
||||
* renumbering.
|
||||
*/
|
||||
if (preexisting && get_dive(preexisting-1) != last)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If any of the new dives already had a number,
|
||||
* we'll have to do a manual renumbering.
|
||||
*/
|
||||
for (i = preexisting; i < dive_table.nr; i++) {
|
||||
struct dive *dive = get_dive(i);
|
||||
if (dive->number)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, renumber..
|
||||
*/
|
||||
if (last)
|
||||
nr = last->number;
|
||||
else
|
||||
nr = 0;
|
||||
for (i = preexisting; i < dive_table.nr; i++) {
|
||||
struct dive *dive = get_dive(i);
|
||||
dive->number = ++nr;
|
||||
}
|
||||
}
|
||||
|
||||
void process_dives(bool is_imported, bool prefer_imported)
|
||||
{
|
||||
int i;
|
||||
int preexisting = dive_table.preexisting;
|
||||
struct dive *last;
|
||||
|
||||
/* check if we need a nickname for the divecomputer for newly downloaded dives;
|
||||
* since we know they all came from the same divecomputer we just check for the
|
||||
* first one */
|
||||
if (preexisting < dive_table.nr && dive_table.dives[preexisting]->downloaded)
|
||||
set_dc_nickname(dive_table.dives[preexisting]);
|
||||
else
|
||||
/* they aren't downloaded, so record / check all new ones */
|
||||
for (i = preexisting; i < dive_table.nr; i++)
|
||||
set_dc_nickname(dive_table.dives[i]);
|
||||
|
||||
/* This does the right thing for -1: NULL */
|
||||
last = get_dive(preexisting-1);
|
||||
|
||||
sort_table(&dive_table);
|
||||
|
||||
for (i = 1; i < dive_table.nr; i++) {
|
||||
struct dive **pp = &dive_table.dives[i-1];
|
||||
struct dive *prev = pp[0];
|
||||
struct dive *dive = pp[1];
|
||||
struct dive *merged;
|
||||
|
||||
/* only try to merge overlapping dives - or if one of the dives has
|
||||
* zero duration (that might be a gps marker from the webservice) */
|
||||
if (prev->duration.seconds && dive->duration.seconds &&
|
||||
prev->when + prev->duration.seconds < dive->when)
|
||||
continue;
|
||||
|
||||
merged = try_to_merge(prev, dive, prefer_imported);
|
||||
if (!merged)
|
||||
continue;
|
||||
|
||||
/* careful - we might free the dive that last points to. Oops... */
|
||||
if (last == prev || last == dive)
|
||||
last = merged;
|
||||
|
||||
/* Redo the new 'i'th dive */
|
||||
i--;
|
||||
add_single_dive(i, merged);
|
||||
delete_single_dive(i+1);
|
||||
delete_single_dive(i+1);
|
||||
}
|
||||
/* make sure no dives are still marked as downloaded */
|
||||
for (i = 1; i < dive_table.nr; i++)
|
||||
dive_table.dives[i]->downloaded = FALSE;
|
||||
|
||||
if (is_imported) {
|
||||
/* If there are dives in the table, are they numbered */
|
||||
if (!last || last->number)
|
||||
try_to_renumber(last, preexisting);
|
||||
|
||||
/* did we add dives to the dive table? */
|
||||
if (preexisting != dive_table.nr)
|
||||
mark_divelist_changed(TRUE);
|
||||
}
|
||||
}
|
||||
|
|
16
divelist.h
16
divelist.h
|
@ -1,8 +1,13 @@
|
|||
#ifndef DIVELIST_H
|
||||
#define DIVELIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dive;
|
||||
|
||||
extern void report_dives(bool imported, bool prefer_imported);
|
||||
extern void dive_list_update_dives(void);
|
||||
extern void update_dive_list_col_visibility(void);
|
||||
extern void update_dive_list_units(void);
|
||||
|
@ -16,12 +21,13 @@ extern void select_prev_dive(void);
|
|||
extern void show_and_select_dive(struct dive *dive);
|
||||
extern double init_decompression(struct dive * dive);
|
||||
extern void export_all_dives_uddf_cb();
|
||||
|
||||
extern void upload_all_dives_divelogs_cb();
|
||||
|
||||
/* divelist core logic functions */
|
||||
extern char *get_dive_date_string(struct tm *tm);
|
||||
extern char *get_trip_date_string(struct tm *tm, int nr);
|
||||
extern void process_dives(bool imported, bool prefer_imported);
|
||||
extern char *get_dive_date_string(timestamp_t when);
|
||||
extern char *get_trip_date_string(timestamp_t when, int nr);
|
||||
extern char *get_nitrox_string(struct dive *dive);
|
||||
extern void clear_trip_indexes(void);
|
||||
extern dive_trip_t *find_trip_by_idx(int idx);
|
||||
extern int dive_nr_sort(int idx_a, int idx_b, timestamp_t when_a, timestamp_t when_b);
|
||||
|
@ -45,4 +51,8 @@ extern void dump_selection(void);
|
|||
extern void dump_trip_list(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,19 +3,23 @@
|
|||
#include "dive.h"
|
||||
#include "divelist.h"
|
||||
#include "display.h"
|
||||
#if USE_GTK_UI
|
||||
#include "display-gtk.h"
|
||||
#include "callbacks-gtk.h"
|
||||
#endif
|
||||
#include "libdivecomputer.h"
|
||||
|
||||
const char *default_dive_computer_vendor;
|
||||
const char *default_dive_computer_product;
|
||||
const char *default_dive_computer_device;
|
||||
|
||||
#if USE_GTK_UI
|
||||
static gboolean force_download;
|
||||
static gboolean prefer_downloaded;
|
||||
|
||||
OPTIONCALLBACK(force_toggle, force_download)
|
||||
OPTIONCALLBACK(prefer_dl_toggle, prefer_downloaded)
|
||||
#endif
|
||||
|
||||
struct product {
|
||||
const char *product;
|
||||
|
@ -38,6 +42,7 @@ struct mydescriptor {
|
|||
|
||||
struct vendor *dc_list;
|
||||
|
||||
#if USE_GTK_UI
|
||||
static void render_dc_vendor(GtkCellLayout *cell,
|
||||
GtkCellRenderer *renderer,
|
||||
GtkTreeModel *model,
|
||||
|
@ -63,6 +68,7 @@ static void render_dc_product(GtkCellLayout *cell,
|
|||
product = dc_descriptor_get_product(descriptor);
|
||||
g_object_set(renderer, "text", product, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
int is_default_dive_computer(const char *vendor, const char *product)
|
||||
{
|
||||
|
@ -75,7 +81,7 @@ int is_default_dive_computer_device(const char *name)
|
|||
return default_dive_computer_device && !strcmp(name, default_dive_computer_device);
|
||||
}
|
||||
|
||||
static void set_default_dive_computer(const char *vendor, const char *product)
|
||||
void set_default_dive_computer(const char *vendor, const char *product)
|
||||
{
|
||||
if (!vendor || !*vendor)
|
||||
return;
|
||||
|
@ -93,7 +99,7 @@ static void set_default_dive_computer(const char *vendor, const char *product)
|
|||
subsurface_set_conf("dive_computer_product", product);
|
||||
}
|
||||
|
||||
static void set_default_dive_computer_device(const char *name)
|
||||
void set_default_dive_computer_device(const char *name)
|
||||
{
|
||||
if (!name || !*name)
|
||||
return;
|
||||
|
@ -105,6 +111,7 @@ static void set_default_dive_computer_device(const char *name)
|
|||
subsurface_set_conf("dive_computer_device", name);
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
static void dive_computer_selector_changed(GtkWidget *combo, gpointer data)
|
||||
{
|
||||
GtkWidget *import, *button;
|
||||
|
@ -161,10 +168,10 @@ static GtkWidget *import_dive_computer(device_data_t *data, GtkDialog *dialog)
|
|||
gtk_box_pack_start(GTK_BOX(vbox), info, FALSE, FALSE, 0);
|
||||
return info;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* create a list of lists and keep the elements sorted */
|
||||
static void add_dc(const char *vendor, const char *product, dc_descriptor_t *descriptor)
|
||||
void add_dc(const char *vendor, const char *product, dc_descriptor_t *descriptor)
|
||||
{
|
||||
struct vendor *dcl = dc_list;
|
||||
struct vendor **dclp = &dc_list;
|
||||
|
@ -207,6 +214,7 @@ static void add_dc(const char *vendor, const char *product, dc_descriptor_t *des
|
|||
pl->descriptor = descriptor;
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
/* fill the vendors and create and fill the respective product stores; return the longest product name
|
||||
* and also the indices of the default vendor / product */
|
||||
static int fill_computer_list(GtkListStore *vendorstore, GtkListStore ***productstore, int *vendor_index, int *product_index)
|
||||
|
@ -485,3 +493,4 @@ void update_progressbar_text(progressbar_t *progress, const char *text)
|
|||
{
|
||||
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress->bar), text);
|
||||
}
|
||||
#endif
|
||||
|
|
46
equipment.c
46
equipment.c
|
@ -16,9 +16,14 @@
|
|||
|
||||
#include "dive.h"
|
||||
#include "display.h"
|
||||
#if USE_GTK_UI
|
||||
#include "display-gtk.h"
|
||||
#endif
|
||||
#include "divelist.h"
|
||||
#include "conversions.h"
|
||||
|
||||
#if USE_GTK_UI
|
||||
#include "display-gtk.h"
|
||||
static GtkListStore *cylinder_model, *weightsystem_model;
|
||||
|
||||
enum {
|
||||
|
@ -68,9 +73,10 @@ struct ws_widget {
|
|||
GtkSpinButton *weight;
|
||||
int w_idx;
|
||||
};
|
||||
#endif /* USE_GTK_UI */
|
||||
|
||||
/* we want bar - so let's not use our unit functions */
|
||||
static int convert_pressure(int mbar, double *p)
|
||||
int convert_pressure(int mbar, double *p)
|
||||
{
|
||||
int decimals = 1;
|
||||
double pressure;
|
||||
|
@ -86,7 +92,7 @@ static int convert_pressure(int mbar, double *p)
|
|||
return decimals;
|
||||
}
|
||||
|
||||
static void convert_volume_pressure(int ml, int mbar, double *v, double *p)
|
||||
void convert_volume_pressure(int ml, int mbar, double *v, double *p)
|
||||
{
|
||||
double volume, pressure;
|
||||
|
||||
|
@ -108,7 +114,7 @@ static void convert_volume_pressure(int ml, int mbar, double *v, double *p)
|
|||
*v = volume;
|
||||
}
|
||||
|
||||
static int convert_weight(int grams, double *m)
|
||||
int convert_weight(int grams, double *m)
|
||||
{
|
||||
int decimals = 1; /* not sure - do people do less than whole lbs/kg ? */
|
||||
double weight;
|
||||
|
@ -121,6 +127,7 @@ static int convert_weight(int grams, double *m)
|
|||
return decimals;
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
static void set_cylinder_description(struct cylinder_widget *cylinder, const char *desc)
|
||||
{
|
||||
set_active_text(cylinder->description, desc);
|
||||
|
@ -452,6 +459,28 @@ static void show_weightsystem(weightsystem_t *ws, struct ws_widget *weightsystem
|
|||
set_weight_description(weightsystem_widget, desc);
|
||||
set_weight_weight_spinbutton(weightsystem_widget, ws->weight.grams);
|
||||
}
|
||||
#else
|
||||
/* placeholders for a few functions that we need to redesign for the Qt UI */
|
||||
void add_cylinder_description(cylinder_type_t *type)
|
||||
{
|
||||
const char *desc;
|
||||
|
||||
desc = type->description;
|
||||
if (!desc)
|
||||
return;
|
||||
/* now do something with it... */
|
||||
}
|
||||
void add_weightsystem_description(weightsystem_t *weightsystem)
|
||||
{
|
||||
const char *desc;
|
||||
|
||||
desc = weightsystem->description;
|
||||
if (!desc)
|
||||
return;
|
||||
/* now do something with it... */
|
||||
}
|
||||
|
||||
#endif /* USE_GTK_UI */
|
||||
|
||||
gboolean cylinder_nodata(cylinder_t *cyl)
|
||||
{
|
||||
|
@ -516,6 +545,7 @@ gboolean weightsystems_equal(weightsystem_t *ws1, weightsystem_t *ws2)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
static void set_one_cylinder(void *_data, GtkListStore *model, GtkTreeIter *iter)
|
||||
{
|
||||
cylinder_t *cyl = _data;
|
||||
|
@ -726,6 +756,7 @@ static void fill_cylinder_info(struct cylinder_widget *cylinder, cylinder_t *cyl
|
|||
/*
|
||||
* Also, insert it into the model if it doesn't already exist
|
||||
*/
|
||||
// WARNING: GTK-Specific Code.
|
||||
add_cylinder(cylinder, desc, ml, mbar);
|
||||
}
|
||||
|
||||
|
@ -784,16 +815,13 @@ static void record_weightsystem_changes(weightsystem_t *ws, struct ws_widget *we
|
|||
ws->description = desc;
|
||||
add_weightsystem_type(desc, grams, &iter);
|
||||
}
|
||||
|
||||
#endif /* USE_GTK_UI */
|
||||
/*
|
||||
* We hardcode the most common standard cylinders,
|
||||
* we should pick up any other names from the dive
|
||||
* logs directly.
|
||||
*/
|
||||
static struct tank_info {
|
||||
const char *name;
|
||||
int cuft, ml, psi, bar;
|
||||
} tank_info[100] = {
|
||||
struct tank_info tank_info[100] = {
|
||||
/* Need an empty entry for the no-cylinder case */
|
||||
{ "", },
|
||||
|
||||
|
@ -836,6 +864,7 @@ static struct tank_info {
|
|||
{ NULL, }
|
||||
};
|
||||
|
||||
#if USE_GTK_UI
|
||||
static void fill_tank_list(GtkListStore *store)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
@ -1682,3 +1711,4 @@ void clear_equipment_widgets()
|
|||
gtk_list_store_clear(cylinder_list[W_IDX_PRIMARY].model);
|
||||
gtk_list_store_clear(weightsystem_list[W_IDX_PRIMARY].model);
|
||||
}
|
||||
#endif /* USE_GTK_UI */
|
||||
|
|
261
gtk-gui.c
261
gtk-gui.c
|
@ -3,6 +3,11 @@
|
|||
/* creates the window and overall layout
|
||||
* divelist, dive info, equipment and printing are handled in their own source files
|
||||
*/
|
||||
/*
|
||||
* This is the former qt-gui.cpp - so it already contains some Qt related
|
||||
* functions. It's renamed back to gtk-ui.c to keep the old Gtk code
|
||||
* around for reference in case we still need it... all that has now been
|
||||
* ripped out of qt-gui.cpp */
|
||||
#include <libintl.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <stdio.h>
|
||||
|
@ -24,19 +29,52 @@
|
|||
#include "webservice.h"
|
||||
#include "version.h"
|
||||
#include "libdivecomputer.h"
|
||||
#include "qt-ui/mainwindow.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gdk-pixbuf/gdk-pixdata.h>
|
||||
#include "subsurface-icon.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QStringList>
|
||||
#include <QTextCodec>
|
||||
#include <QTranslator>
|
||||
|
||||
#include <osm-gps-map-source.h>
|
||||
|
||||
class Translator: public QTranslator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Translator(QObject *parent = 0);
|
||||
~Translator() {}
|
||||
|
||||
virtual QString translate(const char *context, const char *sourceText,
|
||||
const char *disambiguation = NULL) const;
|
||||
};
|
||||
|
||||
Translator::Translator(QObject *parent):
|
||||
QTranslator(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QString Translator::translate(const char *context, const char *sourceText,
|
||||
const char *disambiguation) const
|
||||
{
|
||||
return gettext(sourceText);
|
||||
}
|
||||
|
||||
static const GdkPixdata subsurface_icon_pixbuf = {};
|
||||
|
||||
GtkWidget *main_window;
|
||||
GtkWidget *main_vbox;
|
||||
GtkWidget *error_info_bar;
|
||||
GtkWidget *error_label;
|
||||
GtkWidget *vpane, *hpane;
|
||||
GtkWidget *notebook;
|
||||
static QApplication *application = NULL;
|
||||
|
||||
int error_count;
|
||||
const char *existing_filename;
|
||||
|
@ -93,6 +131,7 @@ static void on_info_bar_response(GtkWidget *widget, gint response,
|
|||
|
||||
void report_error(GError* error)
|
||||
{
|
||||
qDebug("Warning: Calling GTK-Specific Code.");
|
||||
if (error == NULL)
|
||||
{
|
||||
return;
|
||||
|
@ -216,10 +255,12 @@ static void file_save(GtkWidget *w, gpointer data)
|
|||
|
||||
static gboolean ask_save_changes()
|
||||
{
|
||||
//WARNING: Porting to Qt
|
||||
qDebug("This method is being ported to Qt, please, stop using it. ");
|
||||
GtkWidget *dialog, *label, *content;
|
||||
gboolean quit = TRUE;
|
||||
dialog = gtk_dialog_new_with_buttons(_("Save Changes?"),
|
||||
GTK_WINDOW(main_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_WINDOW(main_window), GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
|
||||
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
|
||||
GTK_STOCK_NO, GTK_RESPONSE_NO,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
|
@ -254,6 +295,7 @@ static gboolean ask_save_changes()
|
|||
|
||||
static void file_close(GtkWidget *w, gpointer data)
|
||||
{
|
||||
qDebug("Calling an already ported-to-qt Gtk method");
|
||||
if (unsaved_changes())
|
||||
if (ask_save_changes() == FALSE)
|
||||
return;
|
||||
|
@ -282,8 +324,12 @@ static void file_close(GtkWidget *w, gpointer data)
|
|||
show_dive_info(NULL);
|
||||
}
|
||||
|
||||
//#####################################################################
|
||||
//###### ALREAADY PORTED TO Qt. DELETE ME WHEN NOT MORE USERFUL. #
|
||||
//#####################################################################
|
||||
static void file_open(GtkWidget *w, gpointer data)
|
||||
{
|
||||
qDebug("Calling an already ported-to-qt Gtk method.");
|
||||
GtkWidget *dialog;
|
||||
GtkFileFilter *filter;
|
||||
const char *current_default;
|
||||
|
@ -315,7 +361,7 @@ static void file_open(GtkWidget *w, gpointer data)
|
|||
fn_glist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
|
||||
|
||||
GError *error = NULL;
|
||||
filename = fn_glist->data;
|
||||
filename = (char *)fn_glist->data;
|
||||
parse_file(filename, &error);
|
||||
set_filename(filename, TRUE);
|
||||
if (error != NULL)
|
||||
|
@ -605,16 +651,16 @@ void update_screen()
|
|||
update_dive_list_col_visibility();
|
||||
}
|
||||
|
||||
UNITCALLBACK(set_meter, length, METERS)
|
||||
UNITCALLBACK(set_feet, length, FEET)
|
||||
UNITCALLBACK(set_bar, pressure, BAR)
|
||||
UNITCALLBACK(set_psi, pressure, PSI)
|
||||
UNITCALLBACK(set_liter, volume, LITER)
|
||||
UNITCALLBACK(set_cuft, volume, CUFT)
|
||||
UNITCALLBACK(set_celsius, temperature, CELSIUS)
|
||||
UNITCALLBACK(set_fahrenheit, temperature, FAHRENHEIT)
|
||||
UNITCALLBACK(set_kg, weight, KG)
|
||||
UNITCALLBACK(set_lbs, weight, LBS)
|
||||
UNITCALLBACK(set_meter, length, units::METERS)
|
||||
UNITCALLBACK(set_feet, length, units::FEET)
|
||||
UNITCALLBACK(set_bar, pressure, units::BAR)
|
||||
UNITCALLBACK(set_psi, pressure, units::PSI)
|
||||
UNITCALLBACK(set_liter, volume, units::LITER)
|
||||
UNITCALLBACK(set_cuft, volume, units::CUFT)
|
||||
UNITCALLBACK(set_celsius, temperature, units::CELSIUS)
|
||||
UNITCALLBACK(set_fahrenheit, temperature, units::FAHRENHEIT)
|
||||
UNITCALLBACK(set_kg, weight, units::KG)
|
||||
UNITCALLBACK(set_lbs, weight, units::LBS)
|
||||
|
||||
OPTIONCALLBACK(otu_toggle, prefs.visible_cols.otu)
|
||||
OPTIONCALLBACK(maxcns_toggle, prefs.visible_cols.maxcns)
|
||||
|
@ -664,7 +710,7 @@ static gboolean gfhigh_edit(GtkWidget *w, GdkEvent *event, gpointer _data)
|
|||
|
||||
static void event_toggle(GtkWidget *w, gpointer _data)
|
||||
{
|
||||
gboolean *plot_ev = _data;
|
||||
gboolean *plot_ev = (gboolean *)_data;
|
||||
|
||||
*plot_ev = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
|
||||
}
|
||||
|
@ -707,7 +753,7 @@ static void pick_default_file(GtkWidget *w, GtkButton *button)
|
|||
|
||||
list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(fs_dialog));
|
||||
if (g_slist_length(list) == 1)
|
||||
gtk_button_set_label(button, list->data);
|
||||
gtk_button_set_label(button, (const gchar *)list->data);
|
||||
g_slist_free(list);
|
||||
}
|
||||
|
||||
|
@ -720,7 +766,7 @@ static void pick_default_file(GtkWidget *w, GtkButton *button)
|
|||
|
||||
static GtkWidget * map_provider_widget()
|
||||
{
|
||||
OsmGpsMapSource_t i;
|
||||
int i;
|
||||
#if GTK_CHECK_VERSION(2,24,0)
|
||||
GtkWidget *combobox = gtk_combo_box_text_new();
|
||||
|
||||
|
@ -772,28 +818,28 @@ static void preferences_dialog(GtkWidget *w, gpointer data)
|
|||
gtk_container_add(GTK_CONTAINER(frame), box);
|
||||
|
||||
create_radio(box, _("Depth:"),
|
||||
_("Meter"), set_meter, (prefs.units.length == METERS),
|
||||
_("Feet"), set_feet, (prefs.units.length == FEET),
|
||||
_("Meter"), set_meter, (prefs.units.length == units::METERS),
|
||||
_("Feet"), set_feet, (prefs.units.length == units::FEET),
|
||||
NULL);
|
||||
|
||||
create_radio(box, _("Pressure:"),
|
||||
_("Bar"), set_bar, (prefs.units.pressure == BAR),
|
||||
_("PSI"), set_psi, (prefs.units.pressure == PSI),
|
||||
_("Bar"), set_bar, (prefs.units.pressure == units::BAR),
|
||||
_("PSI"), set_psi, (prefs.units.pressure == units::PSI),
|
||||
NULL);
|
||||
|
||||
create_radio(box, _("Volume:"),
|
||||
_("Liter"), set_liter, (prefs.units.volume == LITER),
|
||||
_("CuFt"), set_cuft, (prefs.units.volume == CUFT),
|
||||
_("Liter"), set_liter, (prefs.units.volume == units::LITER),
|
||||
_("CuFt"), set_cuft, (prefs.units.volume == units::CUFT),
|
||||
NULL);
|
||||
|
||||
create_radio(box, _("Temperature:"),
|
||||
_("Celsius"), set_celsius, (prefs.units.temperature == CELSIUS),
|
||||
_("Fahrenheit"), set_fahrenheit, (prefs.units.temperature == FAHRENHEIT),
|
||||
_("Celsius"), set_celsius, (prefs.units.temperature == units::CELSIUS),
|
||||
_("Fahrenheit"), set_fahrenheit, (prefs.units.temperature == units::FAHRENHEIT),
|
||||
NULL);
|
||||
|
||||
create_radio(box, _("Weight:"),
|
||||
_("kg"), set_kg, (prefs.units.weight == KG),
|
||||
_("lbs"), set_lbs, (prefs.units.weight == LBS),
|
||||
_("kg"), set_kg, (prefs.units.weight == units::KG),
|
||||
_("lbs"), set_lbs, (prefs.units.weight == units::LBS),
|
||||
NULL);
|
||||
|
||||
frame = gtk_frame_new(_("Show Columns"));
|
||||
|
@ -1072,14 +1118,14 @@ static void preferences_dialog(GtkWidget *w, gpointer data)
|
|||
prefs.default_filename = new_default;
|
||||
}
|
||||
/* get the map provider selected */
|
||||
OsmGpsMapSource_t i;
|
||||
int i;
|
||||
#if GTK_CHECK_VERSION(2,24,0)
|
||||
char *provider = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(map_provider));
|
||||
#else
|
||||
char *provider = gtk_combo_box_get_active_text(GTK_COMBO_BOX(map_provider));
|
||||
#endif
|
||||
for (i = OSM_GPS_MAP_SOURCE_OPENSTREETMAP; i <= OSM_GPS_MAP_SOURCE_YAHOO_STREET; i++)
|
||||
if (!strcmp(provider,osm_gps_map_source_get_friendly_name(i))) {
|
||||
if (!strcmp(provider,osm_gps_map_source_get_friendly_name((OsmGpsMapSource_t)i))) {
|
||||
prefs.map_provider = i;
|
||||
break;
|
||||
}
|
||||
|
@ -1097,7 +1143,7 @@ static void preferences_dialog(GtkWidget *w, gpointer data)
|
|||
|
||||
static void create_toggle(const char* label, int *on, void *_data)
|
||||
{
|
||||
GtkWidget *button, *table = _data;
|
||||
GtkWidget *button, *table = GTK_WIDGET(_data);
|
||||
int rows, cols, x, y;
|
||||
static int count;
|
||||
|
||||
|
@ -1413,7 +1459,7 @@ static void edit_dc_delete_rows(GtkTreeView *view)
|
|||
selected_rows = gtk_tree_selection_get_selected_rows(selection, &model);
|
||||
|
||||
for (list = selected_rows; list; list = g_list_next(list)) {
|
||||
path = list->data;
|
||||
path = (GtkTreePath *)list->data;
|
||||
ref = gtk_tree_row_reference_new(model, path);
|
||||
row_references = g_list_append(row_references, ref);
|
||||
}
|
||||
|
@ -1509,7 +1555,7 @@ static void edit_dc_nicknames(GtkWidget *w, gpointer data)
|
|||
|
||||
dialog = gtk_dialog_new_with_buttons(_("Edit Dive Computer Nicknames"),
|
||||
GTK_WINDOW(main_window),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
|
||||
GTK_STOCK_DELETE,
|
||||
SUB_RESPONSE_DELETE,
|
||||
GTK_STOCK_CANCEL,
|
||||
|
@ -1577,7 +1623,7 @@ static void edit_dc_nicknames(GtkWidget *w, gpointer data)
|
|||
if (res == SUB_RESPONSE_DELETE) {
|
||||
confirm = gtk_dialog_new_with_buttons(_("Delete a dive computer information entry"),
|
||||
GTK_WINDOW(dialog),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
|
||||
GTK_STOCK_YES,
|
||||
GTK_RESPONSE_YES,
|
||||
GTK_STOCK_NO,
|
||||
|
@ -1773,8 +1819,143 @@ static gboolean notebook_tooltip (GtkWidget *widget, gint x, gint y,
|
|||
}
|
||||
}
|
||||
|
||||
#if NEEDS_TO_MOVE_TO_QT_UI
|
||||
/* this appears to have moved - but it's very different in qt-ui */
|
||||
|
||||
class MainWindow: public QMainWindow, private Ui::MainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
~MainWindow() {}
|
||||
|
||||
void setCurrentFileName(const QString &fileName);
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_actionNew_triggered() { on_actionClose_triggered(); }
|
||||
void on_actionOpen_triggered();
|
||||
void on_actionSave_triggered() { file_save(NULL, NULL); }
|
||||
void on_actionSaveAs_triggered() { file_save_as(NULL, NULL); }
|
||||
void on_actionClose_triggered();
|
||||
|
||||
private:
|
||||
QStringList fileNameFilters() const;
|
||||
|
||||
private:
|
||||
QString m_currentFileName;
|
||||
};
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent):
|
||||
QMainWindow(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
}
|
||||
|
||||
void MainWindow::setCurrentFileName(const QString &fileName)
|
||||
{
|
||||
if (fileName == m_currentFileName) return;
|
||||
m_currentFileName = fileName;
|
||||
|
||||
QString title = tr("Subsurface");
|
||||
if (!m_currentFileName.isEmpty()) {
|
||||
QFileInfo fileInfo(m_currentFileName);
|
||||
title += " - " + fileInfo.fileName();
|
||||
}
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionOpen_triggered()
|
||||
{
|
||||
QString defaultFileName = prefs.default_filename;
|
||||
QFileInfo fileInfo(defaultFileName);
|
||||
|
||||
QFileDialog dialog(this, tr("Open File"), fileInfo.path());
|
||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||
dialog.selectFile(defaultFileName);
|
||||
dialog.setNameFilters(fileNameFilters());
|
||||
if (dialog.exec()) {
|
||||
/* first, close the existing file, if any */
|
||||
file_close(NULL, NULL);
|
||||
|
||||
/* we know there is only one filename */
|
||||
QString fileName = dialog.selectedFiles().first();
|
||||
GError *error = NULL;
|
||||
parse_file(fileName.toUtf8().constData(), &error);
|
||||
if (error != NULL) {
|
||||
report_error(error);
|
||||
g_error_free(error);
|
||||
error = NULL;
|
||||
} else {
|
||||
setCurrentFileName(fileName);
|
||||
}
|
||||
report_dives(FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionClose_triggered()
|
||||
{
|
||||
if (unsaved_changes())
|
||||
if (ask_save_changes() == FALSE)
|
||||
return;
|
||||
|
||||
setCurrentFileName(QString());
|
||||
|
||||
/* free the dives and trips */
|
||||
while (dive_table.nr)
|
||||
delete_single_dive(0);
|
||||
mark_divelist_changed(FALSE);
|
||||
|
||||
/* clear the selection and the statistics */
|
||||
selected_dive = -1;
|
||||
process_selected_dives();
|
||||
clear_stats_widgets();
|
||||
clear_events();
|
||||
show_dive_stats(NULL);
|
||||
|
||||
/* clear the equipment page */
|
||||
clear_equipment_widgets();
|
||||
|
||||
/* redraw the screen */
|
||||
dive_list_update_dives();
|
||||
show_dive_info(NULL);
|
||||
}
|
||||
|
||||
QStringList MainWindow::fileNameFilters() const
|
||||
{
|
||||
QStringList filters;
|
||||
|
||||
filters << "*.xml *.uddf *.udcf *.jlb"
|
||||
#ifdef LIBZIP
|
||||
" *.sde *.dld"
|
||||
#endif
|
||||
#ifdef SQLITE3
|
||||
" *.db"
|
||||
#endif
|
||||
;
|
||||
return filters;
|
||||
}
|
||||
#endif /* NEEDS_TO_MOVE_TO_QT_UI */
|
||||
|
||||
void init_qt_ui(int *argcp, char ***argvp)
|
||||
{
|
||||
application->installTranslator(new Translator(application));
|
||||
MainWindow *window = new MainWindow();
|
||||
window->show();
|
||||
}
|
||||
|
||||
void init_ui(int *argcp, char ***argvp)
|
||||
{
|
||||
application = new QApplication(*argcp, *argvp);
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
// ask QString in Qt 4 to interpret all char* as UTF-8,
|
||||
// like Qt 5 does.
|
||||
// 106 is "UTF-8", this is faster than lookup by name
|
||||
// [http://www.iana.org/assignments/character-sets/character-sets.xml]
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForMib(106));
|
||||
#endif
|
||||
|
||||
GtkWidget *win;
|
||||
GtkWidget *nb_page;
|
||||
GtkWidget *dive_list;
|
||||
|
@ -1900,11 +2081,12 @@ void init_ui(int *argcp, char ***argvp)
|
|||
|
||||
void run_ui(void)
|
||||
{
|
||||
gtk_main();
|
||||
application->exec();
|
||||
}
|
||||
|
||||
void exit_ui(void)
|
||||
{
|
||||
delete application;
|
||||
subsurface_close_conf();
|
||||
if (existing_filename)
|
||||
free((void *)existing_filename);
|
||||
|
@ -1924,7 +2106,8 @@ static int tooltips;
|
|||
void attach_tooltip(int x, int y, int w, int h, const char *text, struct event *event)
|
||||
{
|
||||
cairo_rectangle_t *rect;
|
||||
tooltip_rects = realloc(tooltip_rects, (tooltips + 1) * sizeof(tooltip_record_t));
|
||||
tooltip_rects = (tooltip_record_t *)
|
||||
realloc(tooltip_rects, (tooltips + 1) * sizeof(tooltip_record_t));
|
||||
rect = &tooltip_rects[tooltips].rect;
|
||||
rect->x = x;
|
||||
rect->y = y;
|
||||
|
@ -2044,7 +2227,7 @@ static gboolean draw_callback(GtkWidget *widget, cairo_t *cr, gpointer data)
|
|||
static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
static struct graphics_context gc = { .printer = 0 };
|
||||
static struct graphics_context gc = { 0 };
|
||||
|
||||
/* the drawing area gives TOTAL width * height - x,y is used as the topx/topy offset
|
||||
* so effective drawing area is width-2x * height-2y */
|
||||
|
@ -2090,7 +2273,7 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer
|
|||
|
||||
static void add_gas_change_cb(GtkWidget *menuitem, gpointer data)
|
||||
{
|
||||
double *x = data;
|
||||
double *x = (double *)data;
|
||||
int when = x_to_time(*x);
|
||||
int cylnr = select_cylinder(current_dive, when);
|
||||
if (cylnr >= 0) {
|
||||
|
@ -2130,7 +2313,7 @@ int confirm_dialog(int when, char *action_text, char *event_text)
|
|||
|
||||
static void add_bookmark_cb(GtkWidget *menuitem, gpointer data)
|
||||
{
|
||||
double *x = data;
|
||||
double *x = (double *)data;
|
||||
int when = x_to_time(*x);
|
||||
|
||||
if (confirm_dialog(when, _("Add"), _("bookmark"))){
|
||||
|
@ -2158,7 +2341,7 @@ static struct event *event_at_x(double rel_x)
|
|||
|
||||
static void remove_event_cb(GtkWidget *menuitem, gpointer data)
|
||||
{
|
||||
struct event *event = data;
|
||||
struct event *event = (struct event *)data;
|
||||
if (confirm_dialog(event->time.seconds, _("Remove"), _(event->name))){
|
||||
struct event **ep = ¤t_dc->events;
|
||||
while (ep && *ep != event)
|
||||
|
@ -2430,3 +2613,5 @@ gdouble get_screen_dpi(void)
|
|||
gdouble dpi_h = floor((h / h_mm) * mm_per_inch);
|
||||
return dpi_h;
|
||||
}
|
||||
|
||||
#include "qt-gui.moc"
|
||||
|
|
19
helpers.h
Normal file
19
helpers.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* helpers.h
|
||||
*
|
||||
* header file for random helper functions of Subsurface
|
||||
*
|
||||
*/
|
||||
#ifndef HELPER_H
|
||||
#define HELPER_H
|
||||
|
||||
#include <QString>
|
||||
#include "dive.h"
|
||||
|
||||
QString get_depth_string(depth_t depth, bool showunit);
|
||||
QString get_weight_string(weight_t weight, bool showunit);
|
||||
QString get_temperature_string(temperature_t temp, bool showunit);
|
||||
QString get_volume_string(volume_t volume, bool showunit);
|
||||
QString get_pressure_string(pressure_t pressure, bool showunit);
|
||||
|
||||
#endif /* HELPER_H */
|
|
@ -796,6 +796,14 @@ int edit_multi_dive_info(struct dive *single_dive)
|
|||
return success;
|
||||
}
|
||||
|
||||
int edit_dive_info(struct dive *dive, gboolean newdive)
|
||||
{
|
||||
if (!dive || (!newdive && !amount_selected))
|
||||
return 0;
|
||||
|
||||
return edit_multi_dive_info(dive);
|
||||
}
|
||||
|
||||
static GtkWidget *frame_box(GtkWidget *vbox, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
|
15
info.c
15
info.c
|
@ -448,10 +448,15 @@ void update_time_depth(struct dive *dive, struct dive *edited)
|
|||
dive->dc.meandepth.mm = edited->dc.meandepth.mm;
|
||||
}
|
||||
|
||||
int edit_dive_info(struct dive *dive, gboolean newdive)
|
||||
void add_people(const char *string)
|
||||
{
|
||||
if (!dive || (!newdive && !amount_selected))
|
||||
return 0;
|
||||
|
||||
return edit_multi_dive_info(dive);
|
||||
/* add names to the completion list for people */
|
||||
}
|
||||
void add_location(const char *string)
|
||||
{
|
||||
/* add names to the completion list for locations */
|
||||
}
|
||||
void add_suit(const char *string)
|
||||
{
|
||||
/* add names to the completion list for suits */
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ static double progress_bar_fraction = 0.0;
|
|||
static int stoptime, stopdepth, ndl, po2, cns;
|
||||
static gboolean in_deco, first_temp_is_air;
|
||||
|
||||
#if USE_GTK_UI
|
||||
static GError *error(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -38,6 +39,7 @@ static GError *error(const char *fmt, ...)
|
|||
va_end(args);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
static dc_status_t create_parser(device_data_t *devdata, dc_parser_t **parser)
|
||||
{
|
||||
|
@ -708,6 +710,7 @@ static const char *do_libdivecomputer_import(device_data_t *data)
|
|||
return err;
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
static void *pthread_wrapper(void *_data)
|
||||
{
|
||||
device_data_t *data = _data;
|
||||
|
@ -772,3 +775,4 @@ GError *do_import(device_data_t *data)
|
|||
return error(retval, data->vendor, data->product, data->devname);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -18,10 +18,12 @@ typedef struct device_data_t {
|
|||
unsigned int deviceid, diveid;
|
||||
dc_device_t *device;
|
||||
dc_context_t *context;
|
||||
progressbar_t progress;
|
||||
int preexisting;
|
||||
gboolean force_download;
|
||||
#if USE_GTK_UI
|
||||
progressbar_t progress;
|
||||
GtkDialog *dialog;
|
||||
#endif
|
||||
} device_data_t;
|
||||
|
||||
extern GError *do_import(device_data_t *data);
|
||||
|
|
25
linux.c
25
linux.c
|
@ -1,7 +1,10 @@
|
|||
/* linux.c */
|
||||
/* implements Linux specific functions */
|
||||
#include "dive.h"
|
||||
#include "display.h"
|
||||
#if USE_GTK_UI
|
||||
#include "display-gtk.h"
|
||||
#endif
|
||||
#include <gconf/gconf-client.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -9,7 +12,7 @@ const char system_divelist_default_font[] = "Sans 8";
|
|||
|
||||
GConfClient *gconf;
|
||||
|
||||
static char *gconf_name(char *name)
|
||||
static char *gconf_name(const char *name)
|
||||
{
|
||||
static char buf[255] = "/apps/subsurface/";
|
||||
|
||||
|
@ -23,32 +26,32 @@ void subsurface_open_conf(void)
|
|||
gconf = gconf_client_get_default();
|
||||
}
|
||||
|
||||
void subsurface_unset_conf(char *name)
|
||||
void subsurface_unset_conf(const char *name)
|
||||
{
|
||||
gconf_client_unset(gconf, gconf_name(name), NULL);
|
||||
}
|
||||
|
||||
void subsurface_set_conf(char *name, const char *value)
|
||||
void subsurface_set_conf(const char *name, const char *value)
|
||||
{
|
||||
gconf_client_set_string(gconf, gconf_name(name), value, NULL);
|
||||
}
|
||||
|
||||
void subsurface_set_conf_bool(char *name, int value)
|
||||
void subsurface_set_conf_bool(const char *name, int value)
|
||||
{
|
||||
gconf_client_set_bool(gconf, gconf_name(name), value > 0, NULL);
|
||||
}
|
||||
|
||||
void subsurface_set_conf_int(char *name, int value)
|
||||
void subsurface_set_conf_int(const char *name, int value)
|
||||
{
|
||||
gconf_client_set_int(gconf, gconf_name(name), value , NULL);
|
||||
}
|
||||
|
||||
const void *subsurface_get_conf(char *name)
|
||||
const char *subsurface_get_conf(const char *name)
|
||||
{
|
||||
return gconf_client_get_string(gconf, gconf_name(name), NULL);
|
||||
}
|
||||
|
||||
int subsurface_get_conf_bool(char *name)
|
||||
int subsurface_get_conf_bool(const char *name)
|
||||
{
|
||||
GConfValue *val;
|
||||
gboolean ret;
|
||||
|
@ -61,7 +64,7 @@ int subsurface_get_conf_bool(char *name)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int subsurface_get_conf_int(char *name)
|
||||
int subsurface_get_conf_int(const char *name)
|
||||
{
|
||||
int val = gconf_client_get_int(gconf, gconf_name(name), NULL);
|
||||
if(!val)
|
||||
|
@ -80,6 +83,7 @@ void subsurface_close_conf(void)
|
|||
/* this is a no-op */
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
int subsurface_fill_device_list(GtkListStore *store)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -139,6 +143,7 @@ int subsurface_fill_device_list(GtkListStore *store)
|
|||
}
|
||||
return index;
|
||||
}
|
||||
#endif /* USE_GTK_UI */
|
||||
|
||||
const char *subsurface_icon_name()
|
||||
{
|
||||
|
@ -170,11 +175,13 @@ const char *subsurface_gettext_domainpath(char *argv0)
|
|||
}
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar,
|
||||
GtkWidget *vbox, GtkUIManager *ui_manager)
|
||||
{
|
||||
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
|
||||
}
|
||||
#endif /* USE_GTK_UI */
|
||||
|
||||
void subsurface_command_line_init(gint *argc, gchar ***argv)
|
||||
{
|
||||
|
@ -191,6 +198,7 @@ gboolean subsurface_os_feature_available(os_feature_t f)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
gboolean subsurface_launch_for_uri(const char* uri)
|
||||
{
|
||||
GError *err = NULL;
|
||||
|
@ -202,3 +210,4 @@ gboolean subsurface_launch_for_uri(const char* uri)
|
|||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* USE_GTK_UI */
|
||||
|
|
26
macos.c
26
macos.c
|
@ -2,7 +2,10 @@
|
|||
/* implements Mac OS X specific functions */
|
||||
#include <stdlib.h>
|
||||
#include "dive.h"
|
||||
#include "display.h"
|
||||
#if USE_GTK_UI
|
||||
#include "display-gtk.h"
|
||||
#endif /* USE_GTK_UI */
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <mach-o/dyld.h>
|
||||
|
@ -30,29 +33,29 @@ void subsurface_open_conf(void)
|
|||
/* nothing at this time */
|
||||
}
|
||||
|
||||
void subsurface_unset_conf(char *name)
|
||||
void subsurface_unset_conf(const char *name)
|
||||
{
|
||||
CFPreferencesSetAppValue(CFSTR_VAR(name), NULL, SUBSURFACE_PREFERENCES);
|
||||
}
|
||||
|
||||
void subsurface_set_conf(char *name, const char *value)
|
||||
void subsurface_set_conf(const char *name, const char *value)
|
||||
{
|
||||
CFPreferencesSetAppValue(CFSTR_VAR(name), CFSTR_VAR(value), SUBSURFACE_PREFERENCES);
|
||||
}
|
||||
|
||||
void subsurface_set_conf_bool(char *name, int value)
|
||||
void subsurface_set_conf_bool(const char *name, int value)
|
||||
{
|
||||
CFPreferencesSetAppValue(CFSTR_VAR(name),
|
||||
value ? kCFBooleanTrue : kCFBooleanFalse, SUBSURFACE_PREFERENCES);
|
||||
}
|
||||
|
||||
void subsurface_set_conf_int(char *name, int value)
|
||||
void subsurface_set_conf_int(const char *name, int value)
|
||||
{
|
||||
CFNumberRef numRef = CFNumberCreate(NULL, kCFNumberIntType, &value);
|
||||
CFPreferencesSetAppValue(CFSTR_VAR(name), numRef, SUBSURFACE_PREFERENCES);
|
||||
}
|
||||
|
||||
const void *subsurface_get_conf(char *name)
|
||||
const char *subsurface_get_conf(const char *name)
|
||||
{
|
||||
CFPropertyListRef strpref;
|
||||
|
||||
|
@ -62,7 +65,7 @@ const void *subsurface_get_conf(char *name)
|
|||
return strdup(CFStringGetCStringPtr(strpref, kCFStringEncodingMacRoman));
|
||||
}
|
||||
|
||||
int subsurface_get_conf_bool(char *name)
|
||||
int subsurface_get_conf_bool(const char *name)
|
||||
{
|
||||
Boolean boolpref, exists;
|
||||
|
||||
|
@ -72,7 +75,7 @@ int subsurface_get_conf_bool(char *name)
|
|||
return boolpref;
|
||||
}
|
||||
|
||||
int subsurface_get_conf_int(char *name)
|
||||
int subsurface_get_conf_int(const char *name)
|
||||
{
|
||||
Boolean exists;
|
||||
CFIndex value;
|
||||
|
@ -151,8 +154,11 @@ const char *subsurface_icon_name()
|
|||
{
|
||||
static char path[PATH_MAX];
|
||||
|
||||
#if USE_GTK_UI
|
||||
snprintf(path, sizeof(path), "%s/%s", gtkosx_application_get_resource_path(), ICON_NAME);
|
||||
|
||||
#else
|
||||
/* need Qt path */
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
|
@ -174,15 +180,18 @@ const char *subsurface_gettext_domainpath(char *argv0)
|
|||
{
|
||||
/* on a Mac we ignore the argv0 argument and instead use the resource_path
|
||||
* to figure out where to find the translation files */
|
||||
#if USE_GTK_UI
|
||||
static char buffer[PATH_MAX];
|
||||
const char *resource_path = gtkosx_application_get_resource_path();
|
||||
if (resource_path) {
|
||||
snprintf(buffer, sizeof(buffer), "%s/share/locale", resource_path);
|
||||
return buffer;
|
||||
}
|
||||
#endif /* USE_GTK_UI */
|
||||
return "./share/locale";
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
static void show_main_window(GtkWidget *w, gpointer data)
|
||||
{
|
||||
gtk_widget_show(main_window);
|
||||
|
@ -230,6 +239,7 @@ void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar,
|
|||
|
||||
gtkosx_application_ready(osx_app);
|
||||
}
|
||||
#endif /* UES_GTK_UI */
|
||||
|
||||
void subsurface_command_line_init(gint *argc, gchar ***argv)
|
||||
{
|
||||
|
|
153
main.c
153
main.c
|
@ -10,7 +10,10 @@
|
|||
#include "dive.h"
|
||||
#include "divelist.h"
|
||||
|
||||
#ifdef USE_GTK_UI
|
||||
#include <osm-gps-map.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
char *debugfilename;
|
||||
FILE *debugfile;
|
||||
|
@ -36,7 +39,9 @@ struct preferences default_prefs = {
|
|||
.calc_ceiling_3m_incr = FALSE,
|
||||
.gflow = 0.30,
|
||||
.gfhigh = 0.75,
|
||||
#ifdef USE_GTK_UI
|
||||
.map_provider = OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* random helper functions, used here or elsewhere */
|
||||
|
@ -76,138 +81,11 @@ const char *monthname(int mon)
|
|||
return _(month_array[mon]);
|
||||
}
|
||||
|
||||
/*
|
||||
* When adding dives to the dive table, we try to renumber
|
||||
* the new dives based on any old dives in the dive table.
|
||||
*
|
||||
* But we only do it if:
|
||||
*
|
||||
* - there are no dives in the dive table
|
||||
*
|
||||
* OR
|
||||
*
|
||||
* - the last dive in the old dive table was numbered
|
||||
*
|
||||
* - all the new dives are strictly at the end (so the
|
||||
* "last dive" is at the same location in the dive table
|
||||
* after re-sorting the dives.
|
||||
*
|
||||
* - none of the new dives have any numbers
|
||||
*
|
||||
* This catches the common case of importing new dives from
|
||||
* a dive computer, and gives them proper numbers based on
|
||||
* your old dive list. But it tries to be very conservative
|
||||
* and not give numbers if there is *any* question about
|
||||
* what the numbers should be - in which case you need to do
|
||||
* a manual re-numbering.
|
||||
*/
|
||||
static void try_to_renumber(struct dive *last, int preexisting)
|
||||
{
|
||||
int i, nr;
|
||||
|
||||
/*
|
||||
* If the new dives aren't all strictly at the end,
|
||||
* we're going to expect the user to do a manual
|
||||
* renumbering.
|
||||
*/
|
||||
if (preexisting && get_dive(preexisting-1) != last)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If any of the new dives already had a number,
|
||||
* we'll have to do a manual renumbering.
|
||||
*/
|
||||
for (i = preexisting; i < dive_table.nr; i++) {
|
||||
struct dive *dive = get_dive(i);
|
||||
if (dive->number)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, renumber..
|
||||
*/
|
||||
if (last)
|
||||
nr = last->number;
|
||||
else
|
||||
nr = 0;
|
||||
for (i = preexisting; i < dive_table.nr; i++) {
|
||||
struct dive *dive = get_dive(i);
|
||||
dive->number = ++nr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* track whether we switched to importing dives
|
||||
*/
|
||||
static gboolean imported = FALSE;
|
||||
|
||||
/*
|
||||
* This doesn't really report anything at all. We just sort the
|
||||
* dives, the GUI does the reporting
|
||||
*/
|
||||
void report_dives(gboolean is_imported, gboolean prefer_imported)
|
||||
{
|
||||
int i;
|
||||
int preexisting = dive_table.preexisting;
|
||||
struct dive *last;
|
||||
|
||||
/* check if we need a nickname for the divecomputer for newly downloaded dives;
|
||||
* since we know they all came from the same divecomputer we just check for the
|
||||
* first one */
|
||||
if (preexisting < dive_table.nr && dive_table.dives[preexisting]->downloaded)
|
||||
set_dc_nickname(dive_table.dives[preexisting]);
|
||||
else
|
||||
/* they aren't downloaded, so record / check all new ones */
|
||||
for (i = preexisting; i < dive_table.nr; i++)
|
||||
set_dc_nickname(dive_table.dives[i]);
|
||||
|
||||
/* This does the right thing for -1: NULL */
|
||||
last = get_dive(preexisting-1);
|
||||
|
||||
sort_table(&dive_table);
|
||||
|
||||
for (i = 1; i < dive_table.nr; i++) {
|
||||
struct dive **pp = &dive_table.dives[i-1];
|
||||
struct dive *prev = pp[0];
|
||||
struct dive *dive = pp[1];
|
||||
struct dive *merged;
|
||||
|
||||
/* only try to merge overlapping dives - or if one of the dives has
|
||||
* zero duration (that might be a gps marker from the webservice) */
|
||||
if (prev->duration.seconds && dive->duration.seconds &&
|
||||
prev->when + prev->duration.seconds < dive->when)
|
||||
continue;
|
||||
|
||||
merged = try_to_merge(prev, dive, prefer_imported);
|
||||
if (!merged)
|
||||
continue;
|
||||
|
||||
/* careful - we might free the dive that last points to. Oops... */
|
||||
if (last == prev || last == dive)
|
||||
last = merged;
|
||||
|
||||
/* Redo the new 'i'th dive */
|
||||
i--;
|
||||
add_single_dive(i, merged);
|
||||
delete_single_dive(i+1);
|
||||
delete_single_dive(i+1);
|
||||
}
|
||||
/* make sure no dives are still marked as downloaded */
|
||||
for (i = 1; i < dive_table.nr; i++)
|
||||
dive_table.dives[i]->downloaded = FALSE;
|
||||
|
||||
if (is_imported) {
|
||||
/* If there are dives in the table, are they numbered */
|
||||
if (!last || last->number)
|
||||
try_to_renumber(last, preexisting);
|
||||
|
||||
/* did we add dives to the dive table? */
|
||||
if (preexisting != dive_table.nr)
|
||||
mark_divelist_changed(TRUE);
|
||||
}
|
||||
dive_list_update_dives();
|
||||
}
|
||||
|
||||
static void parse_argument(const char *arg)
|
||||
{
|
||||
const char *p = arg+1;
|
||||
|
@ -222,7 +100,11 @@ static void parse_argument(const char *arg)
|
|||
if (strcmp(arg,"--import") == 0) {
|
||||
/* mark the dives so far as the base,
|
||||
* everything after is imported */
|
||||
#if USE_GTK_UI
|
||||
report_dives(FALSE, FALSE);
|
||||
#else
|
||||
process_dives(FALSE, FALSE);
|
||||
#endif
|
||||
imported = TRUE;
|
||||
return;
|
||||
}
|
||||
|
@ -242,6 +124,7 @@ static void parse_argument(const char *arg)
|
|||
|
||||
void update_dive(struct dive *new_dive)
|
||||
{
|
||||
#if USE_GTK_UI
|
||||
static struct dive *buffered_dive;
|
||||
struct dive *old_dive = buffered_dive;
|
||||
|
||||
|
@ -252,6 +135,7 @@ void update_dive(struct dive *new_dive)
|
|||
show_dive_equipment(new_dive, W_IDX_PRIMARY);
|
||||
show_dive_stats(new_dive);
|
||||
buffered_dive = new_dive;
|
||||
#endif
|
||||
}
|
||||
|
||||
void renumber_dives(int nr)
|
||||
|
@ -261,7 +145,9 @@ void renumber_dives(int nr)
|
|||
for (i = 0; i < dive_table.nr; i++) {
|
||||
struct dive *dive = dive_table.dives[i];
|
||||
dive->number = nr + i;
|
||||
#if USE_GTK_UI
|
||||
flush_divelist(dive);
|
||||
#endif
|
||||
}
|
||||
mark_divelist_changed(TRUE);
|
||||
}
|
||||
|
@ -331,7 +217,7 @@ int main(int argc, char **argv)
|
|||
subsurface_command_line_init(&argc, &argv);
|
||||
parse_xml_init();
|
||||
|
||||
init_ui(&argc, &argv);
|
||||
init_ui(&argc, &argv); /* the gtk stuff is needed for parsing below */
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *a = argv[i];
|
||||
|
@ -352,7 +238,9 @@ int main(int argc, char **argv)
|
|||
}
|
||||
if (error != NULL)
|
||||
{
|
||||
#if USE_GTK_UI
|
||||
report_error(error);
|
||||
#endif
|
||||
g_error_free(error);
|
||||
error = NULL;
|
||||
}
|
||||
|
@ -365,15 +253,20 @@ int main(int argc, char **argv)
|
|||
sure we remember this as the filename in use */
|
||||
set_filename(filename, FALSE);
|
||||
}
|
||||
#if USE_GTK_UI
|
||||
report_dives(imported, FALSE);
|
||||
if (dive_table.nr == 0)
|
||||
show_dive_info(NULL);
|
||||
run_ui();
|
||||
exit_ui();
|
||||
#else
|
||||
process_dives(imported, FALSE);
|
||||
#endif
|
||||
|
||||
parse_xml_exit();
|
||||
subsurface_command_line_exit(&argc, &argv);
|
||||
|
||||
init_qt_ui(&argc, &argv); /* qt bit delayed until dives are parsed */
|
||||
run_ui();
|
||||
exit_ui();
|
||||
#ifdef DEBUGFILE
|
||||
if (debugfile)
|
||||
fclose(debugfile);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
rm packaging/windows/subsurface.nsi
|
||||
|
||||
export PATH=/usr/i686-w64-mingw32/sys-root/mingw/bin:$PATH
|
||||
make CC=i686-w64-mingw32-gcc \
|
||||
make CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ \
|
||||
PKGCONFIG=i686-w64-mingw32-pkg-config \
|
||||
PKG_CONFIG_PATH=/usr/i686-w64-mingw32/sys-root/mingw/lib/pkgconfig/ \
|
||||
CROSS_PATH=/usr/i686-w64-mingw32/sys-root/mingw/ \
|
||||
|
|
Binary file not shown.
|
@ -699,9 +699,11 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, c
|
|||
stopidx--;
|
||||
}
|
||||
add_plan_to_notes(diveplan, dive);
|
||||
#if USE_GTK_UI
|
||||
/* now make the dive visible in the dive list */
|
||||
report_dives(FALSE, FALSE);
|
||||
show_and_select_dive(dive);
|
||||
#endif
|
||||
error_exit:
|
||||
free(stoplevels);
|
||||
free(gaschanges);
|
||||
|
|
22
pref.h
22
pref.h
|
@ -1,6 +1,10 @@
|
|||
#ifndef PREF_H
|
||||
#define PREF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
gboolean cylinder;
|
||||
gboolean temperature;
|
||||
|
@ -44,13 +48,13 @@ extern struct preferences prefs, default_prefs;
|
|||
#define PP_GRAPHS_ENABLED (prefs.pp_graphs.po2 || prefs.pp_graphs.pn2 || prefs.pp_graphs.phe)
|
||||
|
||||
extern void subsurface_open_conf(void);
|
||||
extern void subsurface_set_conf(char *name, const char *value);
|
||||
extern void subsurface_set_conf_bool(char *name, gboolean value);
|
||||
extern void subsurface_set_conf_int(char *name, int value);
|
||||
extern void subsurface_unset_conf(char *name);
|
||||
extern const void *subsurface_get_conf(char *name);
|
||||
extern int subsurface_get_conf_bool(char *name);
|
||||
extern int subsurface_get_conf_int(char *name);
|
||||
extern void subsurface_set_conf(const char *name, const char *value);
|
||||
extern void subsurface_set_conf_bool(const char *name, gboolean value);
|
||||
extern void subsurface_set_conf_int(const char *name, int value);
|
||||
extern void subsurface_unset_conf(const char *name);
|
||||
extern const char *subsurface_get_conf(const char *name);
|
||||
extern int subsurface_get_conf_bool(const char *name);
|
||||
extern int subsurface_get_conf_int(const char *name);
|
||||
extern void subsurface_flush_conf(void);
|
||||
extern void subsurface_close_conf(void);
|
||||
|
||||
|
@ -60,4 +64,8 @@ extern const char *system_default_filename();
|
|||
extern void load_preferences(void);
|
||||
extern void save_preferences(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PREF_H */
|
||||
|
|
112
profile.h
Normal file
112
profile.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
#ifndef PROFILE_H
|
||||
#define PROFILE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "dive.h"
|
||||
|
||||
typedef enum { STABLE, SLOW, MODERATE, FAST, CRAZY } velocity_t;
|
||||
|
||||
struct divecomputer;
|
||||
struct graphics_context;
|
||||
struct plot_info;
|
||||
struct plot_data {
|
||||
unsigned int in_deco:1;
|
||||
int cylinderindex;
|
||||
int sec;
|
||||
/* pressure[0] is sensor pressure
|
||||
* pressure[1] is interpolated pressure */
|
||||
int pressure[2];
|
||||
int temperature;
|
||||
/* Depth info */
|
||||
int depth;
|
||||
int ceiling;
|
||||
int ndl;
|
||||
int stoptime;
|
||||
int stopdepth;
|
||||
int cns;
|
||||
int smoothed;
|
||||
double po2, pn2, phe;
|
||||
double mod, ead, end, eadd;
|
||||
velocity_t velocity;
|
||||
struct plot_data *min[3];
|
||||
struct plot_data *max[3];
|
||||
int avg[3];
|
||||
};
|
||||
|
||||
void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc);
|
||||
struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc);
|
||||
int setup_temperature_limits(struct graphics_context *gc);
|
||||
int get_cylinder_pressure_range(struct graphics_context *gc);
|
||||
|
||||
struct ev_select {
|
||||
char *ev_name;
|
||||
bool plot_ev;
|
||||
};
|
||||
|
||||
/*
|
||||
* When showing dive profiles, we scale things to the
|
||||
* current dive. However, we don't scale past less than
|
||||
* 30 minutes or 90 ft, just so that small dives show
|
||||
* up as such unless zoom is enabled.
|
||||
* We also need to add 180 seconds at the end so the min/max
|
||||
* plots correctly
|
||||
*/
|
||||
int get_maxtime(struct plot_info *pi);
|
||||
|
||||
/* get the maximum depth to which we want to plot
|
||||
* take into account the additional verical space needed to plot
|
||||
* partial pressure graphs */
|
||||
int get_maxdepth(struct plot_info *pi);
|
||||
|
||||
int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive);
|
||||
|
||||
void setup_pp_limits(struct graphics_context *gc);
|
||||
|
||||
|
||||
#define ALIGN_LEFT 1
|
||||
#define ALIGN_RIGHT 2
|
||||
#define INVISIBLE 4
|
||||
#define UNSORTABLE 8
|
||||
#define EDITABLE 16
|
||||
|
||||
#ifndef TEXT_SCALE
|
||||
#define TEXT_SCALE 1.0
|
||||
#endif
|
||||
|
||||
#define DEPTH_TEXT_SIZE (10 * TEXT_SCALE)
|
||||
#define PRESSURE_TEXT_SIZE (10 * TEXT_SCALE)
|
||||
#define DC_TEXT_SIZE (10.5 * TEXT_SCALE)
|
||||
#define PP_TEXT_SIZE (11 * TEXT_SCALE)
|
||||
#define TEMP_TEXT_SIZE (12 * TEXT_SCALE)
|
||||
|
||||
#define RIGHT (-1.0)
|
||||
#define CENTER (-0.5)
|
||||
#define LEFT (0.0)
|
||||
|
||||
#define TOP (1)
|
||||
#define MIDDLE (0)
|
||||
#define BOTTOM (-1)
|
||||
|
||||
#define SCALEXGC(x) (((x) - gc.leftx) / (gc.rightx - gc.leftx) * gc.maxx)
|
||||
#define SCALEYGC(y) (((y) - gc.topy) / (gc.bottomy - gc.topy) * gc.maxy)
|
||||
#define SCALEGC(x,y) SCALEXGC(x),SCALEYGC(y)
|
||||
|
||||
#define SCALEX(gc,x) (((x)-gc->leftx)/(gc->rightx-gc->leftx)*gc->maxx)
|
||||
#define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy)
|
||||
#define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y)
|
||||
|
||||
#define SENSOR_PR 0
|
||||
#define INTERPOLATED_PR 1
|
||||
#define SENSOR_PRESSURE(_entry) (_entry)->pressure[SENSOR_PR]
|
||||
#define INTERPOLATED_PRESSURE(_entry) (_entry)->pressure[INTERPOLATED_PR]
|
||||
#define GET_PRESSURE(_entry) (SENSOR_PRESSURE(_entry) ? SENSOR_PRESSURE(_entry) : INTERPOLATED_PRESSURE(_entry))
|
||||
|
||||
#define SAC_WINDOW 45 /* sliding window in seconds for current SAC calculation */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
210
qt-gui.cpp
Normal file
210
qt-gui.cpp
Normal file
|
@ -0,0 +1,210 @@
|
|||
/* qt-gui.cpp */
|
||||
/* Qt UI implementation */
|
||||
#include <libintl.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "dive.h"
|
||||
#include "divelist.h"
|
||||
#include "display.h"
|
||||
#include "uemis.h"
|
||||
#include "device.h"
|
||||
#include "webservice.h"
|
||||
#include "version.h"
|
||||
#include "libdivecomputer.h"
|
||||
#include "qt-ui/mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QStringList>
|
||||
#include <QTextCodec>
|
||||
#include <QTranslator>
|
||||
#include <QSettings>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
class Translator: public QTranslator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Translator(QObject *parent = 0);
|
||||
~Translator() {}
|
||||
|
||||
virtual QString translate(const char *context, const char *sourceText,
|
||||
const char *disambiguation = NULL) const;
|
||||
};
|
||||
|
||||
Translator::Translator(QObject *parent):
|
||||
QTranslator(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QString Translator::translate(const char *context, const char *sourceText,
|
||||
const char *disambiguation) const
|
||||
{
|
||||
return gettext(sourceText);
|
||||
}
|
||||
|
||||
static QApplication *application = NULL;
|
||||
|
||||
int error_count;
|
||||
const char *existing_filename;
|
||||
|
||||
void init_qt_ui(int *argcp, char ***argvp)
|
||||
{
|
||||
application->installTranslator(new Translator(application));
|
||||
MainWindow *window = new MainWindow();
|
||||
window->show();
|
||||
}
|
||||
|
||||
void init_ui(int *argcp, char ***argvp)
|
||||
{
|
||||
QVariant v;
|
||||
application = new QApplication(*argcp, *argvp);
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
// ask QString in Qt 4 to interpret all char* as UTF-8,
|
||||
// like Qt 5 does.
|
||||
// 106 is "UTF-8", this is faster than lookup by name
|
||||
// [http://www.iana.org/assignments/character-sets/character-sets.xml]
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForMib(106));
|
||||
#endif
|
||||
|
||||
QSettings settings("hohndel.org","subsurface");
|
||||
settings.beginGroup("GeneralSettings");
|
||||
v = settings.value(QString("default_filename"));
|
||||
if (v.isValid()) {
|
||||
QString name = v.toString();
|
||||
prefs.default_filename = strdup(name.toUtf8());
|
||||
}
|
||||
settings.endGroup();
|
||||
|
||||
#if 0
|
||||
subsurface_open_conf();
|
||||
|
||||
load_preferences();
|
||||
|
||||
/* these still need to be handled in QSettings */
|
||||
default_dive_computer_vendor = subsurface_get_conf("dive_computer_vendor");
|
||||
default_dive_computer_product = subsurface_get_conf("dive_computer_product");
|
||||
default_dive_computer_device = subsurface_get_conf("dive_computer_device");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void run_ui(void)
|
||||
{
|
||||
application->exec();
|
||||
}
|
||||
|
||||
void exit_ui(void)
|
||||
{
|
||||
delete application;
|
||||
#if 0
|
||||
subsurface_close_conf();
|
||||
#endif
|
||||
if (existing_filename)
|
||||
free((void *)existing_filename);
|
||||
if (default_dive_computer_device)
|
||||
free((void *)default_dive_computer_device);
|
||||
}
|
||||
|
||||
void set_filename(const char *filename, gboolean force)
|
||||
{
|
||||
if (!force && existing_filename)
|
||||
return;
|
||||
free((void *)existing_filename);
|
||||
if (filename)
|
||||
existing_filename = strdup(filename);
|
||||
else
|
||||
existing_filename = NULL;
|
||||
}
|
||||
|
||||
const char *get_dc_nickname(const char *model, uint32_t deviceid)
|
||||
{
|
||||
struct device_info *known = get_device_info(model, deviceid);
|
||||
if (known) {
|
||||
if (known->nickname && *known->nickname)
|
||||
return known->nickname;
|
||||
else
|
||||
return known->model;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void set_dc_nickname(struct dive *dive)
|
||||
{
|
||||
/* needs Qt implementation */
|
||||
}
|
||||
|
||||
QString get_depth_string(depth_t depth, bool showunit)
|
||||
{
|
||||
if (prefs.units.length == units::METERS) {
|
||||
double meters = depth.mm / 1000.0;
|
||||
return QString("%1%2").arg(meters, 0, 'f', meters >= 20.0 ? 0 : 1 ).arg(showunit ? _("m") : "");
|
||||
} else {
|
||||
double feet = mm_to_feet(depth.mm);
|
||||
return QString("%1%2").arg(feet, 0, 'f', 1). arg(showunit ? _("ft") : "");
|
||||
}
|
||||
}
|
||||
|
||||
QString get_weight_string(weight_t weight, bool showunit)
|
||||
{
|
||||
if (prefs.units.weight == units::KG) {
|
||||
double kg = weight.grams / 1000.0;
|
||||
return QString("%1%2").arg(kg, 0, 'f', kg >= 20.0 ? 0 : 1 ).arg(showunit ? _("kg") : "");
|
||||
} else {
|
||||
double lbs = grams_to_lbs(weight.grams);
|
||||
return QString("%1%2").arg(lbs, 0, 'f', lbs >= 40.0 ? 0 : 1 ).arg(showunit ? _("lbs") : "");
|
||||
}
|
||||
}
|
||||
|
||||
QString get_temperature_string(temperature_t temp, bool showunit)
|
||||
{
|
||||
if (prefs.units.temperature == units::CELSIUS) {
|
||||
double celsius = mkelvin_to_C(temp.mkelvin);
|
||||
return QString("%1%2%3").arg(celsius, 0, 'f', 1).arg(showunit ? (UTF8_DEGREE): "")
|
||||
.arg(showunit ? _("C") : "");
|
||||
} else {
|
||||
double fahrenheit = mkelvin_to_F(temp.mkelvin);
|
||||
return QString("%1%2%3").arg(fahrenheit, 0, 'f', 1).arg(showunit ? (UTF8_DEGREE): "")
|
||||
.arg(showunit ? _("F") : "");
|
||||
}
|
||||
}
|
||||
|
||||
QString get_volume_string(volume_t volume, bool showunit)
|
||||
{
|
||||
if (prefs.units.volume == units::LITER) {
|
||||
double liter = volume.mliter / 1000.0;
|
||||
return QString("%1%2").arg(liter, 0, 'f', liter >= 40.0 ? 0 : 1 ).arg(showunit ? _("l") : "");
|
||||
} else {
|
||||
double cuft = ml_to_cuft(volume.mliter);
|
||||
return QString("%1%2").arg(cuft, 0, 'f', cuft >= 20.0 ? 0 : (cuft >= 2.0 ? 1 : 2)).arg(showunit ? _("cuft") : "");
|
||||
}
|
||||
}
|
||||
|
||||
QString get_pressure_string(pressure_t pressure, bool showunit)
|
||||
{
|
||||
if (prefs.units.pressure == units::BAR) {
|
||||
double bar = pressure.mbar / 1000.0;
|
||||
return QString("%1%2").arg(bar, 0, 'f', 1).arg(showunit ? _("bar") : "");
|
||||
} else {
|
||||
double psi = mbar_to_PSI(pressure.mbar);
|
||||
return QString("%1%2").arg(psi, 0, 'f', 0).arg(showunit ? _("psi") : "");
|
||||
}
|
||||
}
|
||||
|
||||
double get_screen_dpi()
|
||||
{
|
||||
QDesktopWidget *mydesk = application->desktop();
|
||||
return mydesk->physicalDpiX();
|
||||
}
|
||||
#include "qt-gui.moc"
|
56
qt-ui/addcylinderdialog.cpp
Normal file
56
qt-ui/addcylinderdialog.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* addcylinderdialog.cpp
|
||||
*
|
||||
* classes for the add cylinder dialog of Subsurface
|
||||
*
|
||||
*/
|
||||
#include "addcylinderdialog.h"
|
||||
#include "ui_addcylinderdialog.h"
|
||||
#include <QComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include "../conversions.h"
|
||||
#include "models.h"
|
||||
|
||||
AddCylinderDialog::AddCylinderDialog(QWidget *parent) : ui(new Ui::AddCylinderDialog())
|
||||
, tankInfoModel(new TankInfoModel())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->cylinderType->setModel(tankInfoModel);
|
||||
}
|
||||
|
||||
void AddCylinderDialog::setCylinder(cylinder_t *cylinder)
|
||||
{
|
||||
double volume, pressure;
|
||||
int index;
|
||||
|
||||
currentCylinder = cylinder;
|
||||
convert_volume_pressure(cylinder->type.size.mliter, cylinder->type.workingpressure.mbar, &volume, &pressure);
|
||||
|
||||
index = ui->cylinderType->findText(QString(cylinder->type.description));
|
||||
ui->cylinderType->setCurrentIndex(index);
|
||||
ui->size->setValue(volume);
|
||||
ui->pressure->setValue(pressure);
|
||||
|
||||
ui->o2percent->setValue(cylinder->gasmix.o2.permille / 10.0);
|
||||
ui->hepercent->setValue(cylinder->gasmix.he.permille / 10.0);
|
||||
|
||||
convert_pressure(cylinder->start.mbar, &pressure);
|
||||
ui->start->setValue(pressure);
|
||||
|
||||
convert_pressure(cylinder->end.mbar, &pressure);
|
||||
ui->end->setValue(pressure);
|
||||
}
|
||||
|
||||
void AddCylinderDialog::updateCylinder()
|
||||
{
|
||||
QByteArray description = ui->cylinderType->currentText().toLocal8Bit();
|
||||
|
||||
currentCylinder->type.description = description.data();
|
||||
currentCylinder->type.size.mliter = ui->size->value();
|
||||
currentCylinder->type.workingpressure.mbar = ui->pressure->value();
|
||||
currentCylinder->gasmix.o2.permille = ui->o2percent->value();
|
||||
currentCylinder->gasmix.he.permille = ui->hepercent->value();
|
||||
currentCylinder->start.mbar = ui->start->value();
|
||||
currentCylinder->end.mbar = ui->end->value();
|
||||
}
|
||||
|
33
qt-ui/addcylinderdialog.h
Normal file
33
qt-ui/addcylinderdialog.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* addcylinderdialog.h
|
||||
*
|
||||
* header file for the add cylinder dialog of Subsurface
|
||||
*
|
||||
*/
|
||||
#ifndef ADDCYLINDERDIALOG_H
|
||||
#define ADDCYLINDERDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "../dive.h"
|
||||
|
||||
namespace Ui{
|
||||
class AddCylinderDialog;
|
||||
}
|
||||
|
||||
class TankInfoModel;
|
||||
|
||||
class AddCylinderDialog : public QDialog{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AddCylinderDialog(QWidget* parent = 0);
|
||||
void setCylinder(cylinder_t *cylinder);
|
||||
void updateCylinder();
|
||||
|
||||
private:
|
||||
Ui::AddCylinderDialog *ui;
|
||||
cylinder_t *currentCylinder;
|
||||
TankInfoModel *tankInfoModel;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
303
qt-ui/addcylinderdialog.ui
Normal file
303
qt-ui/addcylinderdialog.ui
Normal file
|
@ -0,0 +1,303 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AddCylinderDialog</class>
|
||||
<widget class="QDialog" name="AddCylinderDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>408</width>
|
||||
<height>298</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Cylinder</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cylinderType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="size">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Pressure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="pressure">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Pressure</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>End</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="start">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="end">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Gas Mix</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>O2%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="o2percent">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>He%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="hepercent">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_2">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<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>AddCylinderDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>269</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AddCylinderDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>290</x>
|
||||
<y>269</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkBox</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>start</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>216</x>
|
||||
<y>46</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>280</x>
|
||||
<y>66</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkBox</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>end</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>226</x>
|
||||
<y>48</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>268</x>
|
||||
<y>100</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkBox_2</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>o2percent</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>214</x>
|
||||
<y>165</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>260</x>
|
||||
<y>190</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkBox_2</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>hepercent</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>228</x>
|
||||
<y>165</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>262</x>
|
||||
<y>216</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
39
qt-ui/addweightsystemdialog.cpp
Normal file
39
qt-ui/addweightsystemdialog.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* addweightsystemdialog.cpp
|
||||
*
|
||||
* classes for the add weightsystem dialog of Subsurface
|
||||
*
|
||||
*/
|
||||
#include "addweightsystemdialog.h"
|
||||
#include "ui_addweightsystemdialog.h"
|
||||
#include <QComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include "../conversions.h"
|
||||
#include "models.h"
|
||||
|
||||
AddWeightsystemDialog::AddWeightsystemDialog(QWidget *parent) : ui(new Ui::AddWeightsystemDialog())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
currentWeightsystem = NULL;
|
||||
}
|
||||
|
||||
void AddWeightsystemDialog::setWeightsystem(weightsystem_t *ws)
|
||||
{
|
||||
currentWeightsystem = ws;
|
||||
|
||||
ui->description->insert(QString(ws->description));
|
||||
if (get_units()->weight == units::KG)
|
||||
ui->weight->setValue(ws->weight.grams / 1000);
|
||||
else
|
||||
ui->weight->setValue(grams_to_lbs(ws->weight.grams));
|
||||
}
|
||||
|
||||
void AddWeightsystemDialog::updateWeightsystem()
|
||||
{
|
||||
currentWeightsystem->description = strdup(ui->description->text().toUtf8().data());
|
||||
if (get_units()->weight == units::KG)
|
||||
currentWeightsystem->weight.grams = ui->weight->value() * 1000;
|
||||
else
|
||||
currentWeightsystem->weight.grams = lbs_to_grams(ui->weight->value());
|
||||
}
|
||||
|
30
qt-ui/addweightsystemdialog.h
Normal file
30
qt-ui/addweightsystemdialog.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* addweightsystemdialog.h
|
||||
*
|
||||
* header file for the add weightsystem dialog of Subsurface
|
||||
*
|
||||
*/
|
||||
#ifndef ADDWEIGHTSYSTEMDIALOG_H
|
||||
#define ADDWEIGHTSYSTEMDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "../dive.h"
|
||||
|
||||
namespace Ui{
|
||||
class AddWeightsystemDialog;
|
||||
}
|
||||
|
||||
class AddWeightsystemDialog : public QDialog{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AddWeightsystemDialog(QWidget* parent = 0);
|
||||
void setWeightsystem(weightsystem_t *ws);
|
||||
void updateWeightsystem();
|
||||
|
||||
private:
|
||||
Ui::AddWeightsystemDialog *ui;
|
||||
weightsystem_t *currentWeightsystem;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
109
qt-ui/addweightsystemdialog.ui
Normal file
109
qt-ui/addweightsystemdialog.ui
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AddWeightsystemDialog</class>
|
||||
<widget class="QDialog" name="AddWeightsystemDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>408</width>
|
||||
<height>186</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Weightsystem</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Description</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Weight</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="weight">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="inputMethodHints">
|
||||
<set>Qt::ImhFormattedNumbersOnly</set>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="description"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<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>AddWeightsystemDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>269</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AddWeightsystemDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>290</x>
|
||||
<y>269</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
132
qt-ui/divelistview.cpp
Normal file
132
qt-ui/divelistview.cpp
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* divelistview.cpp
|
||||
*
|
||||
* classes for the divelist of Subsurface
|
||||
*
|
||||
*/
|
||||
#include "divelistview.h"
|
||||
#include "models.h"
|
||||
#include "modeldelegates.h"
|
||||
#include <QApplication>
|
||||
#include <QHeaderView>
|
||||
#include <QDebug>
|
||||
#include <QKeyEvent>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
|
||||
DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false)
|
||||
{
|
||||
setUniformRowHeights(true);
|
||||
setItemDelegateForColumn(TreeItemDT::RATING, new StarWidgetsDelegate());
|
||||
QSortFilterProxyModel *model = new QSortFilterProxyModel(this);
|
||||
setModel(model);
|
||||
}
|
||||
|
||||
void DiveListView::reload()
|
||||
{
|
||||
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(model());
|
||||
QAbstractItemModel *oldModel = m->sourceModel();
|
||||
if (oldModel)
|
||||
oldModel->deleteLater();
|
||||
m->setSourceModel(new DiveTripModel(this));
|
||||
sortByColumn(0, Qt::DescendingOrder);
|
||||
QModelIndex firstDiveOrTrip = m->index(0,0);
|
||||
if (firstDiveOrTrip.isValid()){
|
||||
if (m->index(0,0, firstDiveOrTrip).isValid())
|
||||
setCurrentIndex(m->index(0,0, firstDiveOrTrip));
|
||||
else
|
||||
setCurrentIndex(firstDiveOrTrip);
|
||||
}
|
||||
}
|
||||
|
||||
void DiveListView::setModel(QAbstractItemModel* model)
|
||||
{
|
||||
QTreeView::setModel(model);
|
||||
}
|
||||
|
||||
void DiveListView::setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags command)
|
||||
{
|
||||
if (mouseClickSelection)
|
||||
QTreeView::setSelection(rect, command);
|
||||
}
|
||||
|
||||
void DiveListView::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
mouseClickSelection = true;
|
||||
QTreeView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void DiveListView::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
mouseClickSelection = false;
|
||||
QTreeView::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void DiveListView::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if(event->modifiers())
|
||||
mouseClickSelection = true;
|
||||
QTreeView::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void DiveListView::keyReleaseEvent(QKeyEvent* event)
|
||||
{
|
||||
mouseClickSelection = false;
|
||||
QWidget::keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
void DiveListView::currentChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||
{
|
||||
if (!current.isValid())
|
||||
return;
|
||||
const QAbstractItemModel *model = current.model();
|
||||
int selectedDive = 0;
|
||||
struct dive *dive = (struct dive*) model->data(current, TreeItemDT::DIVE_ROLE).value<void*>();
|
||||
if (!dive) { // it's a trip! select first child.
|
||||
dive = (struct dive*) model->data(current.child(0,0), TreeItemDT::DIVE_ROLE).value<void*>();
|
||||
selectedDive = get_divenr(dive);
|
||||
}else{
|
||||
selectedDive = get_divenr(dive);
|
||||
}
|
||||
if (selectedDive == selected_dive)
|
||||
return;
|
||||
Q_EMIT currentDiveChanged(selectedDive);
|
||||
}
|
||||
|
||||
void DiveListView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
|
||||
{
|
||||
QList<QModelIndex> parents;
|
||||
Q_FOREACH(const QModelIndex& index, deselected.indexes()) {
|
||||
const QAbstractItemModel *model = index.model();
|
||||
struct dive *dive = (struct dive*) model->data(index, TreeItemDT::DIVE_ROLE).value<void*>();
|
||||
if (!dive) { // it's a trip!
|
||||
if (model->rowCount(index)) {
|
||||
expand(index); // leave this - even if it looks like it shouldn't be here. looks like I've found a Qt bug.
|
||||
// the subselection is removed, but the painting is not. this cleans the area.
|
||||
}
|
||||
} else if (!parents.contains(index.parent())) {
|
||||
parents.push_back(index.parent());
|
||||
}
|
||||
}
|
||||
|
||||
Q_FOREACH(const QModelIndex& index, selected.indexes()) {
|
||||
const QAbstractItemModel *model = index.model();
|
||||
struct dive *dive = (struct dive*) model->data(index, TreeItemDT::DIVE_ROLE).value<void*>();
|
||||
if (!dive) { // it's a trip!
|
||||
if (model->rowCount(index)) {
|
||||
QItemSelection selection;
|
||||
selection.select(index.child(0,0), index.child(model->rowCount(index) -1 , 0));
|
||||
selectionModel()->select(selection, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select | QItemSelectionModel::NoUpdate);
|
||||
if (!isExpanded(index)) {
|
||||
expand(index);
|
||||
}
|
||||
}
|
||||
} else if (!parents.contains(index.parent())) {
|
||||
parents.push_back(index.parent());
|
||||
}
|
||||
}
|
||||
|
||||
Q_FOREACH(const QModelIndex& index, parents)
|
||||
expand(index);
|
||||
}
|
40
qt-ui/divelistview.h
Normal file
40
qt-ui/divelistview.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* divelistview.h
|
||||
*
|
||||
* header file for the dive list of Subsurface
|
||||
*
|
||||
*/
|
||||
#ifndef DIVELISTVIEW_H
|
||||
#define DIVELISTVIEW_H
|
||||
|
||||
/*! A view subclass for use with dives
|
||||
|
||||
Note: calling this a list view might be misleading?
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <QTreeView>
|
||||
|
||||
class DiveListView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DiveListView(QWidget *parent = 0);
|
||||
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
void currentChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||
void setModel(QAbstractItemModel* model);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void keyReleaseEvent(QKeyEvent*);
|
||||
void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags command);
|
||||
void reload();
|
||||
|
||||
Q_SIGNALS:
|
||||
void currentDiveChanged(int divenr);
|
||||
private:
|
||||
bool mouseClickSelection;
|
||||
};
|
||||
|
||||
#endif // DIVELISTVIEW_H
|
113
qt-ui/globe.cpp
Normal file
113
qt-ui/globe.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include "globe.h"
|
||||
#include "../dive.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <marble/AbstractFloatItem.h>
|
||||
#include <marble/GeoDataPlacemark.h>
|
||||
#include <marble/GeoDataDocument.h>
|
||||
#include <marble/MarbleModel.h>
|
||||
#include <marble/GeoDataTreeModel.h>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QMessageBox>
|
||||
|
||||
GlobeGPS::GlobeGPS(QWidget* parent) : MarbleWidget(parent), loadedDives(0)
|
||||
{
|
||||
setMapThemeId("earth/bluemarble/bluemarble.dgml");
|
||||
setProjection( Marble::Spherical );
|
||||
|
||||
setAnimationsEnabled(true);
|
||||
setShowClouds( false );
|
||||
setShowBorders( false );
|
||||
setShowPlaces( false );
|
||||
setShowCrosshairs( false );
|
||||
setShowGrid( false );
|
||||
setShowOverviewMap(false);
|
||||
setShowScaleBar(false);
|
||||
|
||||
Q_FOREACH( AbstractFloatItem * floatItem, floatItems() ){
|
||||
if ( floatItem && floatItem->nameId() == "compass" ) {
|
||||
floatItem->setPosition( QPoint( 10, 10 ) );
|
||||
floatItem->setContentSize( QSize( 50, 50 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlobeGPS::reload()
|
||||
{
|
||||
if (loadedDives){
|
||||
model()->treeModel()->removeDocument(loadedDives);
|
||||
delete loadedDives;
|
||||
}
|
||||
if (editingDiveCoords){
|
||||
editingDiveCoords = 0;
|
||||
}
|
||||
|
||||
loadedDives = new GeoDataDocument;
|
||||
|
||||
int idx = 0;
|
||||
struct dive *dive;
|
||||
for_each_dive(idx, dive) {
|
||||
if (dive_has_gps_location(dive)) {
|
||||
// don't add dive locations twice.
|
||||
if( diveLocations.contains( QString(dive->location)))
|
||||
continue;
|
||||
|
||||
GeoDataPlacemark *place = new GeoDataPlacemark( dive->location );
|
||||
place->setCoordinate(dive->longitude.udeg / 1000000.0,dive->latitude.udeg / 1000000.0 , 0, GeoDataCoordinates::Degree );
|
||||
loadedDives->append( place );
|
||||
}
|
||||
}
|
||||
model()->treeModel()->addDocument( loadedDives );
|
||||
}
|
||||
|
||||
void GlobeGPS::centerOn(dive* dive)
|
||||
{
|
||||
qreal longitude = dive->longitude.udeg / 1000000.0;
|
||||
qreal latitude = dive->latitude.udeg / 1000000.0;
|
||||
|
||||
if (!longitude || !latitude){
|
||||
prepareForGetDiveCoordinates(dive);
|
||||
return;
|
||||
}
|
||||
|
||||
centerOn(longitude,latitude, true);
|
||||
}
|
||||
|
||||
void GlobeGPS::prepareForGetDiveCoordinates(dive* dive)
|
||||
{
|
||||
QMessageBox::warning(parentWidget(),
|
||||
tr("This dive has no location!"),
|
||||
tr("Move the planet to the desired position, then \n double-click to set the new location of this dive."));
|
||||
|
||||
editingDiveCoords = dive;
|
||||
}
|
||||
|
||||
void GlobeGPS::changeDiveGeoPosition(qreal lon, qreal lat, GeoDataCoordinates::Unit unit)
|
||||
{
|
||||
// convert to degrees if in radian.
|
||||
if (unit == GeoDataCoordinates::Radian){
|
||||
lon = lon * 180 / M_PI;
|
||||
lat = lat * 180 / M_PI;
|
||||
}
|
||||
|
||||
if (!editingDiveCoords){
|
||||
return;
|
||||
}
|
||||
|
||||
editingDiveCoords->latitude.udeg = (int) lat * 1000000.0;
|
||||
editingDiveCoords->longitude.udeg = (int) lon * 1000000.0;
|
||||
centerOn(lon, lat, true);
|
||||
reload();
|
||||
editingDiveCoords = 0;
|
||||
}
|
||||
|
||||
void GlobeGPS::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
qreal lat, lon;
|
||||
if (editingDiveCoords && geoCoordinates(event->pos().x(), event->pos().y(), lon,lat, GeoDataCoordinates::Radian)){
|
||||
changeDiveGeoPosition(lon, lat, GeoDataCoordinates::Radian);
|
||||
}
|
||||
}
|
||||
|
34
qt-ui/globe.h
Normal file
34
qt-ui/globe.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef GLOBE_H
|
||||
#define GLOBE_H
|
||||
|
||||
#include <marble/MarbleWidget.h>
|
||||
#include <marble/GeoDataCoordinates.h>
|
||||
|
||||
#include <QHash>
|
||||
|
||||
using namespace Marble;
|
||||
struct dive;
|
||||
|
||||
class GlobeGPS : public MarbleWidget{
|
||||
Q_OBJECT
|
||||
void prepareForGetDiveCoordinates(struct dive* dive);
|
||||
public:
|
||||
using MarbleWidget::centerOn;
|
||||
GlobeGPS(QWidget *parent);
|
||||
void reload();
|
||||
void centerOn(struct dive* dive);
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent* event);
|
||||
|
||||
private:
|
||||
GeoDataDocument *loadedDives;
|
||||
QStringList diveLocations;
|
||||
struct dive* editingDiveCoords;
|
||||
|
||||
public Q_SLOTS:
|
||||
void changeDiveGeoPosition(qreal lon,qreal lat,GeoDataCoordinates::Unit);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
204
qt-ui/maintab.cpp
Normal file
204
qt-ui/maintab.cpp
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* maintab.cpp
|
||||
*
|
||||
* classes for the "notebook" area of the main window of Subsurface
|
||||
*
|
||||
*/
|
||||
#include "maintab.h"
|
||||
#include "ui_maintab.h"
|
||||
#include "addcylinderdialog.h"
|
||||
#include "addweightsystemdialog.h"
|
||||
#include "../helpers.h"
|
||||
#include "../statistics.h"
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
|
||||
ui(new Ui::MainTab()),
|
||||
weightModel(new WeightModel()),
|
||||
cylindersModel(new CylindersModel())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->cylinders->setModel(cylindersModel);
|
||||
ui->weights->setModel(weightModel);
|
||||
|
||||
/* example of where code is more concise than Qt designer */
|
||||
QList<QObject *> infoTabWidgets = ui->infoTab->children();
|
||||
Q_FOREACH( QObject* obj, infoTabWidgets ){
|
||||
QLabel* label = qobject_cast<QLabel *>(obj);
|
||||
if (label)
|
||||
label->setAlignment(Qt::AlignHCenter);
|
||||
}
|
||||
QList<QObject *> statisticsTabWidgets = ui->statisticsTab->children();
|
||||
Q_FOREACH( QObject* obj, statisticsTabWidgets ){
|
||||
QLabel* label = qobject_cast<QLabel *>(obj);
|
||||
if (label)
|
||||
label->setAlignment(Qt::AlignHCenter);
|
||||
}
|
||||
}
|
||||
|
||||
void MainTab::clearEquipment()
|
||||
{
|
||||
}
|
||||
|
||||
void MainTab::clearInfo()
|
||||
{
|
||||
ui->sacText->clear();
|
||||
ui->otuText->clear();
|
||||
ui->oxygenHeliumText->clear();
|
||||
ui->gasUsedText->clear();
|
||||
ui->dateText->clear();
|
||||
ui->diveTimeText->clear();
|
||||
ui->surfaceIntervalText->clear();
|
||||
ui->maximumDepthText->clear();
|
||||
ui->averageDepthText->clear();
|
||||
ui->visibilityText->clear();
|
||||
ui->waterTemperatureText->clear();
|
||||
ui->airTemperatureText->clear();
|
||||
ui->airPressureText->clear();
|
||||
}
|
||||
|
||||
void MainTab::clearStats()
|
||||
{
|
||||
ui->maximumDepthAllText->clear();
|
||||
ui->minimumDepthAllText->clear();
|
||||
ui->averageDepthAllText->clear();
|
||||
ui->maximumSacAllText->clear();
|
||||
ui->minimumSacAllText->clear();
|
||||
ui->averageSacAllText->clear();
|
||||
ui->divesAllText->clear();
|
||||
ui->maximumTemperatureAllText->clear();
|
||||
ui->minimumTemperatureAllText->clear();
|
||||
ui->averageTemperatureAllText->clear();
|
||||
ui->totalTimeAllText->clear();
|
||||
ui->averageTimeAllText->clear();
|
||||
ui->longestAllText->clear();
|
||||
ui->shortestAllText->clear();
|
||||
}
|
||||
|
||||
#define UPDATE_TEXT(d, field) \
|
||||
if (!d || !d->field) \
|
||||
ui->field->setText(""); \
|
||||
else \
|
||||
ui->field->setText(d->field)
|
||||
|
||||
|
||||
void MainTab::updateDiveInfo(int dive)
|
||||
{
|
||||
// So, this is what happens now:
|
||||
// Every tab should be populated from this method,
|
||||
// it will be called whenever a new dive is selected
|
||||
// I'm already populating the 'notes' box
|
||||
// to show how it can be done.
|
||||
// If you are unsure about the name of something,
|
||||
// open the file maintab.ui on the designer
|
||||
// click on the item and check its objectName,
|
||||
// the access is ui->objectName from here on.
|
||||
volume_t sacVal;
|
||||
struct dive *d = get_dive(dive);
|
||||
UPDATE_TEXT(d, notes);
|
||||
UPDATE_TEXT(d, location);
|
||||
UPDATE_TEXT(d, suit);
|
||||
UPDATE_TEXT(d, divemaster);
|
||||
UPDATE_TEXT(d, buddy);
|
||||
/* infoTab */
|
||||
if (d) {
|
||||
ui->rating->setCurrentStars(d->rating);
|
||||
ui->maximumDepthText->setText(get_depth_string(d->maxdepth, TRUE));
|
||||
ui->averageDepthText->setText(get_depth_string(d->meandepth, TRUE));
|
||||
ui->otuText->setText(QString("%1").arg(d->otu));
|
||||
ui->waterTemperatureText->setText(get_temperature_string(d->watertemp, TRUE));
|
||||
ui->airTemperatureText->setText(get_temperature_string(d->airtemp, TRUE));
|
||||
ui->gasUsedText->setText(get_volume_string(get_gas_used(d), TRUE));
|
||||
if ((sacVal.mliter = d->sac) > 0)
|
||||
ui->sacText->setText(get_volume_string(sacVal, TRUE).append("/min"));
|
||||
else
|
||||
ui->sacText->clear();
|
||||
if (d->surface_pressure.mbar)
|
||||
/* this is ALWAYS displayed in mbar */
|
||||
ui->airPressureText->setText(QString("%1mbar").arg(d->surface_pressure.mbar));
|
||||
else
|
||||
ui->airPressureText->clear();
|
||||
} else {
|
||||
ui->rating->setCurrentStars(0);
|
||||
ui->sacText->clear();
|
||||
ui->otuText->clear();
|
||||
ui->oxygenHeliumText->clear();
|
||||
ui->dateText->clear();
|
||||
ui->diveTimeText->clear();
|
||||
ui->surfaceIntervalText->clear();
|
||||
ui->maximumDepthText->clear();
|
||||
ui->averageDepthText->clear();
|
||||
ui->visibilityText->clear();
|
||||
ui->waterTemperatureText->clear();
|
||||
ui->airTemperatureText->clear();
|
||||
ui->gasUsedText->clear();
|
||||
ui->airPressureText->clear();
|
||||
}
|
||||
/* statisticsTab*/
|
||||
/* we can access the stats_selection struct, but how do we ensure the relevant dives are selected
|
||||
* if we don't use the gtk widget to drive this?
|
||||
* Maybe call process_selected_dives? Or re-write to query our Qt list view.
|
||||
*/
|
||||
// qDebug("max temp %u",stats_selection.max_temp);
|
||||
// qDebug("min temp %u",stats_selection.min_temp);
|
||||
}
|
||||
|
||||
void MainTab::on_addCylinder_clicked()
|
||||
{
|
||||
if (cylindersModel->rowCount() >= MAX_CYLINDERS)
|
||||
return;
|
||||
|
||||
AddCylinderDialog dialog(this);
|
||||
cylinder_t *newCylinder = (cylinder_t*) malloc(sizeof(cylinder_t));
|
||||
newCylinder->type.description = "";
|
||||
|
||||
dialog.setCylinder(newCylinder);
|
||||
int result = dialog.exec();
|
||||
if (result == QDialog::Rejected){
|
||||
return;
|
||||
}
|
||||
|
||||
dialog.updateCylinder();
|
||||
cylindersModel->add(newCylinder);
|
||||
}
|
||||
|
||||
void MainTab::on_editCylinder_clicked()
|
||||
{
|
||||
}
|
||||
|
||||
void MainTab::on_delCylinder_clicked()
|
||||
{
|
||||
}
|
||||
|
||||
void MainTab::on_addWeight_clicked()
|
||||
{
|
||||
if (weightModel->rowCount() >= MAX_WEIGHTSYSTEMS)
|
||||
return;
|
||||
|
||||
AddWeightsystemDialog dialog(this);
|
||||
weightsystem_t newWeightsystem;
|
||||
newWeightsystem.description = "";
|
||||
newWeightsystem.weight.grams = 0;
|
||||
|
||||
dialog.setWeightsystem(&newWeightsystem);
|
||||
int result = dialog.exec();
|
||||
if (result == QDialog::Rejected)
|
||||
return;
|
||||
|
||||
dialog.updateWeightsystem();
|
||||
weightModel->add(&newWeightsystem);
|
||||
}
|
||||
|
||||
void MainTab::on_editWeight_clicked()
|
||||
{
|
||||
}
|
||||
|
||||
void MainTab::on_delWeight_clicked()
|
||||
{
|
||||
}
|
||||
|
||||
void MainTab::reload()
|
||||
{
|
||||
cylindersModel->update();
|
||||
}
|
46
qt-ui/maintab.h
Normal file
46
qt-ui/maintab.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* maintab.h
|
||||
*
|
||||
* header file for the main tab of Subsurface
|
||||
*
|
||||
*/
|
||||
#ifndef MAINTAB_H
|
||||
#define MAINTAB_H
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QDialog>
|
||||
|
||||
#include "models.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MainTab;
|
||||
}
|
||||
|
||||
class MainTab : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainTab(QWidget *parent);
|
||||
void clearStats();
|
||||
void clearInfo();
|
||||
void clearEquipment();
|
||||
void reload();
|
||||
|
||||
public Q_SLOTS:
|
||||
void on_addCylinder_clicked();
|
||||
void on_editCylinder_clicked();
|
||||
void on_delCylinder_clicked();
|
||||
void on_addWeight_clicked();
|
||||
void on_editWeight_clicked();
|
||||
void on_delWeight_clicked();
|
||||
|
||||
void updateDiveInfo(int dive);
|
||||
|
||||
private:
|
||||
Ui::MainTab *ui;
|
||||
WeightModel *weightModel;
|
||||
CylindersModel *cylindersModel;
|
||||
};
|
||||
|
||||
#endif
|
885
qt-ui/maintab.ui
Normal file
885
qt-ui/maintab.ui
Normal file
|
@ -0,0 +1,885 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainTab</class>
|
||||
<widget class="QTabWidget" name="MainTab">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>325</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>TabWidget</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="notesTab">
|
||||
<attribute name="title">
|
||||
<string>Dive Notes</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLineEdit" name="location"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Divemaster</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Buddy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLineEdit" name="divemaster"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="buddy"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Rating</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Suit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="suit"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Notes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QTextEdit" name="notes"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="StarWidget" name="rating" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="equipmentTab">
|
||||
<attribute name="title">
|
||||
<string>Equipment</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Cylinders</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTableView" name="cylinders"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="editCylinder">
|
||||
<property name="text">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addCylinder">
|
||||
<property name="text">
|
||||
<string>Add</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>
|
||||
<widget class="QPushButton" name="delCylinder">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Weight</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTableView" name="weights"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="editWeight">
|
||||
<property name="text">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addWeight">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<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>
|
||||
<widget class="QPushButton" name="delWeight">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="infoTab">
|
||||
<attribute name="title">
|
||||
<string>Dive Info</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="diveInfoUpperGridLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="sacLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>SAC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="outLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>OTU</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="oxygenHeliumLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0²/He</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="gasUsedLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Gas Used</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="gasUsedText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="sacText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="otuText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="oxygenHeliumText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="diveInfoLowerGridLayout">
|
||||
<property name="margin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="dateLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Date</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="maximumDepthText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="visibilityText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="visibilityLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Visibility</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="waterTempertureLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Water Temp.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="airTemperatureText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="diveTimeText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="surfaceIntervalText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="airPressureLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Air Pressure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="averageDepthLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ave. Depth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="maximumDepthLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max. Depth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="airTempertatureLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Air Temp.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="averageDepthText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="airPressureText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="waterTemperatureText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="dateText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="surfaceIntervalLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Interval</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="diveTimeLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dive Time</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="statisticsTab">
|
||||
<attribute name="title">
|
||||
<string>Stats</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="statsUpperGridLayout">
|
||||
<property name="margin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="maximumDepthAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max. Depth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="minimumDepthAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min. Depth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="averageDepthAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ave. Depth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="maximumDepthAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="minimumDepthAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="averageDepthAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="maximumSacAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max. SAC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="minimumSacAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min. SAC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="averageSacAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ave. SAC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="maximumSacAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="minimumSacAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="averageSacAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="statsLowerGridLayout">
|
||||
<property name="margin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="divesAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dives</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="maximumTemperatureLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max. Temp.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="minimumTemperatureAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min. Temp.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="averageTemperatureAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ave. Temp.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="divesAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="maximumTemperatureAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="minimumTemperatureAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="averageTemperatureAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="totalTimeAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Total Time</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="averageTimeAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ave. Time</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="longestAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Longest</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLabel" name="shortestAllLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shortest</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="totalTimeAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="averageTimeAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="longestAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLabel" name="shortestAllText">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>StarWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>starwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
464
qt-ui/mainwindow.cpp
Normal file
464
qt-ui/mainwindow.cpp
Normal file
|
@ -0,0 +1,464 @@
|
|||
/*
|
||||
* mainwindow.cpp
|
||||
*
|
||||
* classes for the main UI window in Subsurface
|
||||
*/
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QtDebug>
|
||||
#include <QDateTime>
|
||||
#include <QSettings>
|
||||
#include <QCloseEvent>
|
||||
#include <QApplication>
|
||||
#include <QFontMetrics>
|
||||
|
||||
#include "divelistview.h"
|
||||
#include "starwidget.h"
|
||||
|
||||
#include "glib.h"
|
||||
#include "../dive.h"
|
||||
#include "../divelist.h"
|
||||
#include "../pref.h"
|
||||
#include "modeldelegates.h"
|
||||
#include "models.h"
|
||||
|
||||
MainWindow::MainWindow() : ui(new Ui::MainWindow())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
readSettings();
|
||||
setWindowIcon(QIcon(":subsurface-icon"));
|
||||
connect(ui->ListWidget, SIGNAL(currentDiveChanged(int)), this, SLOT(current_dive_changed(int)));
|
||||
ui->ProfileWidget->setFocusProxy(ui->ListWidget);
|
||||
ui->ListWidget->reload();
|
||||
ui->ListWidget->setFocus();
|
||||
ui->widget->reload();
|
||||
}
|
||||
|
||||
void MainWindow::current_dive_changed(int divenr)
|
||||
{
|
||||
select_dive(divenr);
|
||||
ui->widget->centerOn(get_dive(selected_dive));
|
||||
redrawProfile();
|
||||
ui->InfoWidget->updateDiveInfo(divenr);
|
||||
}
|
||||
|
||||
void MainWindow::redrawProfile()
|
||||
{
|
||||
ui->ProfileWidget->plot(get_dive(selected_dive));
|
||||
}
|
||||
|
||||
void MainWindow::on_actionNew_triggered()
|
||||
{
|
||||
qDebug("actionNew");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionOpen_triggered()
|
||||
{
|
||||
QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::homePath(), filter());
|
||||
if (filename.isEmpty())
|
||||
return;
|
||||
|
||||
// Needed to convert to char*
|
||||
QByteArray fileNamePtr = filename.toLocal8Bit();
|
||||
|
||||
on_actionClose_triggered();
|
||||
|
||||
GError *error = NULL;
|
||||
parse_file(fileNamePtr.data(), &error);
|
||||
set_filename(fileNamePtr.data(), TRUE);
|
||||
|
||||
if (error != NULL) {
|
||||
QMessageBox::warning(this, "Error", error->message);
|
||||
g_error_free(error);
|
||||
error = NULL;
|
||||
}
|
||||
process_dives(FALSE, FALSE);
|
||||
|
||||
ui->InfoWidget->reload();
|
||||
ui->widget->reload();
|
||||
ui->ListWidget->reload();
|
||||
ui->ListWidget->setFocus();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSave_triggered()
|
||||
{
|
||||
qDebug("actionSave");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSaveAs_triggered()
|
||||
{
|
||||
qDebug("actionSaveAs");
|
||||
}
|
||||
void MainWindow::on_actionClose_triggered()
|
||||
{
|
||||
if (unsaved_changes() && (askSaveChanges() == FALSE))
|
||||
return;
|
||||
|
||||
/* free the dives and trips */
|
||||
while (dive_table.nr)
|
||||
delete_single_dive(0);
|
||||
|
||||
/* clear the selection and the statistics */
|
||||
selected_dive = -1;
|
||||
|
||||
//WARNING: Port this to Qt.
|
||||
//process_selected_dives();
|
||||
|
||||
ui->InfoWidget->clearStats();
|
||||
ui->InfoWidget->clearInfo();
|
||||
ui->InfoWidget->clearEquipment();
|
||||
ui->ProfileWidget->clear();
|
||||
ui->ListWidget->reload();
|
||||
|
||||
clear_events();
|
||||
#if USE_GTK_UI
|
||||
show_dive_stats(NULL);
|
||||
|
||||
/* redraw the screen */
|
||||
//WARNING: Port this to Qt.
|
||||
dive_list_update_dives();
|
||||
|
||||
// WARNING? Port this to Qt.
|
||||
show_dive_info(NULL);
|
||||
#endif /* USE_GTK_UI */
|
||||
}
|
||||
|
||||
void MainWindow::on_actionImport_triggered()
|
||||
{
|
||||
qDebug("actionImport");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionExportUDDF_triggered()
|
||||
{
|
||||
qDebug("actionExportUDDF");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionPrint_triggered()
|
||||
{
|
||||
qDebug("actionPrint");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionPreferences_triggered()
|
||||
{
|
||||
qDebug("actionPreferences");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionQuit_triggered()
|
||||
{
|
||||
if (unsaved_changes() && (askSaveChanges() == FALSE))
|
||||
return;
|
||||
writeSettings();
|
||||
QApplication::quit();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionDownloadDC_triggered()
|
||||
{
|
||||
qDebug("actionDownloadDC");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionDownloadWeb_triggered()
|
||||
{
|
||||
qDebug("actionDownloadWeb");}
|
||||
|
||||
void MainWindow::on_actionEditDeviceNames_triggered()
|
||||
{
|
||||
qDebug("actionEditDeviceNames");}
|
||||
|
||||
void MainWindow::on_actionAddDive_triggered()
|
||||
{
|
||||
qDebug("actionAddDive");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionRenumber_triggered()
|
||||
{
|
||||
qDebug("actionRenumber");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionAutoGroup_triggered()
|
||||
{
|
||||
qDebug("actionAutoGroup");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionToggleZoom_triggered()
|
||||
{
|
||||
qDebug("actionToggleZoom");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionYearlyStatistics_triggered()
|
||||
{
|
||||
qDebug("actionYearlyStatistics");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionViewList_triggered()
|
||||
{
|
||||
ui->InfoWidget->setVisible(false);
|
||||
ui->ListWidget->setVisible(true);
|
||||
ui->ProfileWidget->setVisible(false);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionViewProfile_triggered()
|
||||
{
|
||||
ui->InfoWidget->setVisible(false);
|
||||
ui->ListWidget->setVisible(false);
|
||||
ui->ProfileWidget->setVisible(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionViewInfo_triggered()
|
||||
{
|
||||
ui->InfoWidget->setVisible(true);
|
||||
ui->ListWidget->setVisible(false);
|
||||
ui->ProfileWidget->setVisible(false);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionViewAll_triggered()
|
||||
{
|
||||
ui->InfoWidget->setVisible(true);
|
||||
ui->ListWidget->setVisible(true);
|
||||
ui->ProfileWidget->setVisible(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionPreviousDC_triggered()
|
||||
{
|
||||
dc_number--;
|
||||
redrawProfile();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionNextDC_triggered()
|
||||
{
|
||||
dc_number++;
|
||||
redrawProfile();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSelectEvents_triggered()
|
||||
{
|
||||
qDebug("actionSelectEvents");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionInputPlan_triggered()
|
||||
{
|
||||
qDebug("actionInputPlan");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionAboutSubsurface_triggered()
|
||||
{
|
||||
qDebug("actionAboutSubsurface");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionUserManual_triggered()
|
||||
{
|
||||
qDebug("actionUserManual");
|
||||
}
|
||||
|
||||
QString MainWindow::filter()
|
||||
{
|
||||
QString f;
|
||||
f += "ALL ( *.xml *.XML *.uddf *.udcf *.UDFC *.jlb *.JLB ";
|
||||
#ifdef LIBZIP
|
||||
f += "*.sde *.SDE *.dld *.DLD ";
|
||||
#endif
|
||||
#ifdef SQLITE3
|
||||
f += "*.db";
|
||||
#endif
|
||||
f += ");;";
|
||||
|
||||
f += "XML (*.xml *.XML);;";
|
||||
f += "UDDF (*.uddf);;";
|
||||
f += "UDCF (*.udcf *.UDCF);;";
|
||||
f += "JLB (*.jlb *.JLB);;";
|
||||
|
||||
#ifdef LIBZIP
|
||||
f += "SDE (*.sde *.SDE);;";
|
||||
f += "DLD (*.dld *.DLD);;";
|
||||
#endif
|
||||
#ifdef SQLITE3
|
||||
f += "DB (*.db)";
|
||||
#endif
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
bool MainWindow::askSaveChanges()
|
||||
{
|
||||
QString message = ! existing_filename ? tr("You have unsaved changes\nWould you like to save those before closing the datafile?")
|
||||
: tr("You have unsaved changes to file: %1 \nWould you like to save those before closing the datafile?").arg(existing_filename);
|
||||
|
||||
if (QMessageBox::question(this, tr("Save Changes?"), message) == QMessageBox::Ok) {
|
||||
// WARNING: Port.
|
||||
// file_save(NULL,NULL);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define GET_UNIT(v, name, field, f, t) \
|
||||
v = settings.value(QString(name)); \
|
||||
if (v.isValid()) \
|
||||
prefs.units.field = (v.toInt() == (t)) ? (t) : (f)
|
||||
|
||||
#define GET_BOOL(v, name, field) \
|
||||
v = settings.value(QString(name)); \
|
||||
if (v.isValid() && v.toInt()) \
|
||||
field = TRUE; \
|
||||
else \
|
||||
field = FALSE
|
||||
|
||||
void MainWindow::readSettings()
|
||||
{
|
||||
int i;
|
||||
QVariant v;
|
||||
QSettings settings("hohndel.org","subsurface");
|
||||
|
||||
settings.beginGroup("MainWindow");
|
||||
QSize sz = settings.value("size").value<QSize>();
|
||||
resize(sz);
|
||||
ui->mainSplitter->restoreState(settings.value("mainSplitter").toByteArray());
|
||||
ui->infoProfileSplitter->restoreState(settings.value("infoProfileSplitter").toByteArray());
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("ListWidget");
|
||||
/* if no width are set, use the calculated width for each column;
|
||||
* for that to work we need to temporarily expand all rows */
|
||||
ui->ListWidget->expandAll();
|
||||
for (i = TreeItemDT::NR; i < TreeItemDT::COLUMNS; i++) {
|
||||
QVariant width = settings.value(QString("colwidth%1").arg(i));
|
||||
if (width.isValid())
|
||||
ui->ListWidget->setColumnWidth(i, width.toInt());
|
||||
else
|
||||
ui->ListWidget->resizeColumnToContents(i);
|
||||
}
|
||||
ui->ListWidget->collapseAll();
|
||||
ui->ListWidget->scrollTo(ui->ListWidget->model()->index(0,0), QAbstractItemView::PositionAtCenter);
|
||||
|
||||
settings.endGroup();
|
||||
settings.beginGroup("Units");
|
||||
GET_UNIT(v, "feet", length, units::METERS, units::FEET);
|
||||
GET_UNIT(v, "psi", pressure, units::BAR, units::PSI);
|
||||
GET_UNIT(v, "cuft", volume, units::LITER, units::CUFT);
|
||||
GET_UNIT(v, "fahrenheit", temperature, units::CELSIUS, units::FAHRENHEIT);
|
||||
GET_UNIT(v, "lbs", weight, units::KG, units::LBS);
|
||||
settings.endGroup();
|
||||
settings.beginGroup("DisplayListColumns");
|
||||
GET_BOOL(v, "CYLINDER", prefs.visible_cols.cylinder);
|
||||
GET_BOOL(v, "TEMPERATURE", prefs.visible_cols.temperature);
|
||||
GET_BOOL(v, "TOTALWEIGHT", prefs.visible_cols.totalweight);
|
||||
GET_BOOL(v, "SUIT", prefs.visible_cols.suit);
|
||||
GET_BOOL(v, "NITROX", prefs.visible_cols.nitrox);
|
||||
GET_BOOL(v, "OTU", prefs.visible_cols.otu);
|
||||
GET_BOOL(v, "MAXCNS", prefs.visible_cols.maxcns);
|
||||
GET_BOOL(v, "SAC", prefs.visible_cols.sac);
|
||||
GET_BOOL(v, "po2graph", prefs.pp_graphs.po2);
|
||||
GET_BOOL(v, "pn2graph", prefs.pp_graphs.pn2);
|
||||
GET_BOOL(v, "phegraph", prefs.pp_graphs.phe);
|
||||
settings.endGroup();
|
||||
settings.beginGroup("TecDetails");
|
||||
v = settings.value(QString("po2threshold"));
|
||||
if (v.isValid())
|
||||
prefs.pp_graphs.po2_threshold = v.toDouble();
|
||||
v = settings.value(QString("pn2threshold"));
|
||||
if (v.isValid())
|
||||
prefs.pp_graphs.pn2_threshold = v.toDouble();
|
||||
v = settings.value(QString("phethreshold"));
|
||||
if (v.isValid())
|
||||
prefs.pp_graphs.phe_threshold = v.toDouble();
|
||||
GET_BOOL(v, "mod", prefs.mod);
|
||||
v = settings.value(QString("modppO2"));
|
||||
if (v.isValid())
|
||||
prefs.mod_ppO2 = v.toDouble();
|
||||
GET_BOOL(v, "ead", prefs.ead);
|
||||
GET_BOOL(v, "redceiling", prefs.profile_red_ceiling);
|
||||
GET_BOOL(v, "calcceiling", prefs.profile_calc_ceiling);
|
||||
GET_BOOL(v, "calcceiling3m", prefs.calc_ceiling_3m_incr);
|
||||
v = settings.value(QString("gflow"));
|
||||
if (v.isValid())
|
||||
prefs.gflow = v.toInt() / 100.0;
|
||||
v = settings.value(QString("gfhigh"));
|
||||
if (v.isValid())
|
||||
prefs.gfhigh = v.toInt() / 100.0;
|
||||
set_gf(prefs.gflow, prefs.gfhigh);
|
||||
settings.endGroup();
|
||||
|
||||
#if ONCE_WE_CAN_SET_FONTS
|
||||
settings.beginGroup("Display");
|
||||
v = settings.value(QString("divelist_font"));
|
||||
if (v.isValid())
|
||||
/* I don't think this is right */
|
||||
prefs.divelist_font = strdup(v.toString);
|
||||
#endif
|
||||
|
||||
#if ONCE_WE_HAVE_MAPS
|
||||
v = settings.value(QString_int("map_provider"));
|
||||
if(v.isValid())
|
||||
prefs.map_provider = v.toInt();
|
||||
#endif
|
||||
}
|
||||
|
||||
#define SAVE_VALUE(name, field) \
|
||||
if (prefs.field != default_prefs.field) \
|
||||
settings.setValue(name, prefs.field)
|
||||
|
||||
void MainWindow::writeSettings()
|
||||
{
|
||||
int i;
|
||||
QSettings settings("hohndel.org","subsurface");
|
||||
|
||||
settings.beginGroup("MainWindow");
|
||||
settings.setValue("size",size());
|
||||
settings.setValue("mainSplitter", ui->mainSplitter->saveState());
|
||||
settings.setValue("infoProfileSplitter", ui->infoProfileSplitter->saveState());
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("ListWidget");
|
||||
for (i = TreeItemDT::NR; i < TreeItemDT::COLUMNS; i++)
|
||||
settings.setValue(QString("colwidth%1").arg(i), ui->ListWidget->columnWidth(i));
|
||||
settings.endGroup();
|
||||
settings.beginGroup("Units");
|
||||
SAVE_VALUE("feet", units.length);
|
||||
SAVE_VALUE("psi", units.pressure);
|
||||
SAVE_VALUE("cuft", units.volume);
|
||||
SAVE_VALUE("fahrenheit", units.temperature);
|
||||
SAVE_VALUE("lbs", units.weight);
|
||||
settings.endGroup();
|
||||
settings.beginGroup("DisplayListColumns");
|
||||
SAVE_VALUE("TEMPERATURE", visible_cols.temperature);
|
||||
SAVE_VALUE("TOTALWEIGHT", visible_cols.totalweight);
|
||||
SAVE_VALUE("SUIT", visible_cols.suit);
|
||||
SAVE_VALUE("CYLINDER", visible_cols.cylinder);
|
||||
SAVE_VALUE("NITROX", visible_cols.nitrox);
|
||||
SAVE_VALUE("SAC", visible_cols.sac);
|
||||
SAVE_VALUE("OTU", visible_cols.otu);
|
||||
SAVE_VALUE("MAXCNS", visible_cols.maxcns);
|
||||
settings.endGroup();
|
||||
settings.beginGroup("TecDetails");
|
||||
SAVE_VALUE("po2graph", pp_graphs.po2);
|
||||
SAVE_VALUE("pn2graph", pp_graphs.pn2);
|
||||
SAVE_VALUE("phegraph", pp_graphs.phe);
|
||||
SAVE_VALUE("po2threshold", pp_graphs.po2_threshold);
|
||||
SAVE_VALUE("pn2threshold", pp_graphs.pn2_threshold);
|
||||
SAVE_VALUE("phethreshold", pp_graphs.phe_threshold);
|
||||
SAVE_VALUE("mod", mod);
|
||||
SAVE_VALUE("modppO2", mod_ppO2);
|
||||
SAVE_VALUE("ead", ead);
|
||||
SAVE_VALUE("redceiling", profile_red_ceiling);
|
||||
SAVE_VALUE("calcceiling", profile_calc_ceiling);
|
||||
SAVE_VALUE("calcceiling3m", calc_ceiling_3m_incr);
|
||||
SAVE_VALUE("gflow", gflow);
|
||||
SAVE_VALUE("gfhigh", gfhigh);
|
||||
settings.endGroup();
|
||||
settings.beginGroup("GeneralSettings");
|
||||
SAVE_VALUE("default_filename", default_filename);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (unsaved_changes() && (askSaveChanges() == FALSE)) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
event->accept();
|
||||
writeSettings();
|
||||
}
|
89
qt-ui/mainwindow.h
Normal file
89
qt-ui/mainwindow.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* mainwindow.h
|
||||
*
|
||||
* header file for the main window of Subsurface
|
||||
*
|
||||
*/
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QModelIndex>
|
||||
#include <QAction>
|
||||
|
||||
class QSortFilterProxyModel;
|
||||
class DiveTripModel;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class DiveInfo;
|
||||
class DiveNotes;
|
||||
class Stats;
|
||||
class Equipment;
|
||||
class QItemSelection;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
/* file menu action */
|
||||
void on_actionNew_triggered();
|
||||
void on_actionOpen_triggered();
|
||||
void on_actionSave_triggered();
|
||||
void on_actionSaveAs_triggered();
|
||||
void on_actionClose_triggered();
|
||||
void on_actionImport_triggered();
|
||||
void on_actionExportUDDF_triggered();
|
||||
void on_actionPrint_triggered();
|
||||
void on_actionPreferences_triggered();
|
||||
void on_actionQuit_triggered();
|
||||
|
||||
/* log menu actions */
|
||||
void on_actionDownloadDC_triggered();
|
||||
void on_actionDownloadWeb_triggered();
|
||||
void on_actionEditDeviceNames_triggered();
|
||||
void on_actionAddDive_triggered();
|
||||
void on_actionRenumber_triggered();
|
||||
void on_actionAutoGroup_triggered();
|
||||
void on_actionToggleZoom_triggered();
|
||||
void on_actionYearlyStatistics_triggered();
|
||||
|
||||
/* view menu actions */
|
||||
void on_actionViewList_triggered();
|
||||
void on_actionViewProfile_triggered();
|
||||
void on_actionViewInfo_triggered();
|
||||
void on_actionViewAll_triggered();
|
||||
void on_actionPreviousDC_triggered();
|
||||
void on_actionNextDC_triggered();
|
||||
|
||||
/* other menu actions */
|
||||
void on_actionSelectEvents_triggered();
|
||||
void on_actionInputPlan_triggered();
|
||||
void on_actionAboutSubsurface_triggered();
|
||||
void on_actionUserManual_triggered();
|
||||
|
||||
void current_dive_changed(int divenr);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
QAction *actionNextDive;
|
||||
QAction *actionPreviousDive;
|
||||
|
||||
QString filter();
|
||||
bool askSaveChanges();
|
||||
void readSettings();
|
||||
void writeSettings();
|
||||
void redrawProfile();
|
||||
};
|
||||
|
||||
#endif
|
383
qt-ui/mainwindow.ui
Normal file
383
qt-ui/mainwindow.ui
Normal file
|
@ -0,0 +1,383 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>763</width>
|
||||
<height>548</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="mainSplitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QSplitter" name="infoProfileSplitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="MainTab" name="InfoWidget" native="true"/>
|
||||
<widget class="ProfileGraphicsView" name="ProfileWidget"/>
|
||||
</widget>
|
||||
<widget class="QSplitter" name="globeListSplitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="DiveListView" name="ListWidget">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"> QTreeView {
|
||||
show-decoration-selected: 1;
|
||||
}
|
||||
|
||||
QTreeView::item {
|
||||
border: 1px solid #d9d9d9;
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
QTreeView::item:hover {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);
|
||||
border: 1px solid #bfcde4;
|
||||
}
|
||||
|
||||
QTreeView::item:selected {
|
||||
border: 1px solid #567dbc;
|
||||
}
|
||||
|
||||
QTreeView::item:selected:active{
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6ea1f1, stop: 1 #567dbc);
|
||||
}
|
||||
|
||||
QTreeView::item:selected:!active {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6b9be8, stop: 1 #577fbf);
|
||||
}
|
||||
|
||||
</string>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="allColumnsShowFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="GlobeGPS" name="widget" native="true"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>763</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="actionNew"/>
|
||||
<addaction name="actionOpen"/>
|
||||
<addaction name="actionSave"/>
|
||||
<addaction name="actionSaveAs"/>
|
||||
<addaction name="actionClose"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionImport"/>
|
||||
<addaction name="actionExportUDDF"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionPrint"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionPreferences"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionQuit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuLog">
|
||||
<property name="title">
|
||||
<string>Log</string>
|
||||
</property>
|
||||
<addaction name="actionDownloadDC"/>
|
||||
<addaction name="actionDownloadWeb"/>
|
||||
<addaction name="actionEditDeviceNames"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAddDive"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionRenumber"/>
|
||||
<addaction name="actionAutoGroup"/>
|
||||
<addaction name="actionToggleZoom"/>
|
||||
<addaction name="actionYearlyStatistics"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
<string>View</string>
|
||||
</property>
|
||||
<addaction name="actionViewList"/>
|
||||
<addaction name="actionViewProfile"/>
|
||||
<addaction name="actionViewInfo"/>
|
||||
<addaction name="actionViewAll"/>
|
||||
<addaction name="actionPreviousDC"/>
|
||||
<addaction name="actionNextDC"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuFilter">
|
||||
<property name="title">
|
||||
<string>Filter</string>
|
||||
</property>
|
||||
<addaction name="actionSelectEvents"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuPlanner">
|
||||
<property name="title">
|
||||
<string>Planner</string>
|
||||
</property>
|
||||
<addaction name="actionInputPlan"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuHelp">
|
||||
<property name="title">
|
||||
<string>Help</string>
|
||||
</property>
|
||||
<addaction name="actionAboutSubsurface"/>
|
||||
<addaction name="actionUserManual"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuLog"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuFilter"/>
|
||||
<addaction name="menuPlanner"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<action name="actionNew">
|
||||
<property name="text">
|
||||
<string>New</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+N</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpen">
|
||||
<property name="text">
|
||||
<string>Open</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+O</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveAs">
|
||||
<property name="text">
|
||||
<string>Save as</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+S</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClose">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+W</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionImport">
|
||||
<property name="text">
|
||||
<string>Import Files</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+I</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExportUDDF">
|
||||
<property name="text">
|
||||
<string>Export UDDF</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPrint">
|
||||
<property name="text">
|
||||
<string>Print</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+P</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPreferences">
|
||||
<property name="text">
|
||||
<string>Preferences</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQuit">
|
||||
<property name="text">
|
||||
<string>Quit</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Q</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDownloadDC">
|
||||
<property name="text">
|
||||
<string>Download from Dive computer</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+D</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDownloadWeb">
|
||||
<property name="text">
|
||||
<string>Download from Web Service</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEditDeviceNames">
|
||||
<property name="text">
|
||||
<string>Edit Device Names</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddDive">
|
||||
<property name="text">
|
||||
<string>Add Dive</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRenumber">
|
||||
<property name="text">
|
||||
<string>Renumber</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAutoGroup">
|
||||
<property name="text">
|
||||
<string>Auto Group</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionToggleZoom">
|
||||
<property name="text">
|
||||
<string>Toggle Zoom</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionYearlyStatistics">
|
||||
<property name="text">
|
||||
<string>Yearly Statistics</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewList">
|
||||
<property name="text">
|
||||
<string>View List</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+1</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewProfile">
|
||||
<property name="text">
|
||||
<string>View Profile</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+2</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewInfo">
|
||||
<property name="text">
|
||||
<string>View Info</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+3</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewAll">
|
||||
<property name="text">
|
||||
<string>View All</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+4</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPreviousDC">
|
||||
<property name="text">
|
||||
<string>Prev DC</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNextDC">
|
||||
<property name="text">
|
||||
<string>Next DC</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSelectEvents">
|
||||
<property name="text">
|
||||
<string>Select Events</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionInputPlan">
|
||||
<property name="text">
|
||||
<string>Input Plan</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAboutSubsurface">
|
||||
<property name="text">
|
||||
<string>About Subsurface</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUserManual">
|
||||
<property name="text">
|
||||
<string>User Manual</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>MainTab</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>maintab.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>DiveListView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>divelistview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ProfileGraphicsView</class>
|
||||
<extends>QGraphicsView</extends>
|
||||
<header>profilegraphics.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GlobeGPS</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>globe.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
49
qt-ui/modeldelegates.cpp
Normal file
49
qt-ui/modeldelegates.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include "modeldelegates.h"
|
||||
#include "../dive.h"
|
||||
#include "../divelist.h"
|
||||
#include "starwidget.h"
|
||||
#include "models.h"
|
||||
|
||||
#include <QtDebug>
|
||||
#include <QPainter>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
|
||||
StarWidgetsDelegate::StarWidgetsDelegate(QWidget* parent):
|
||||
QStyledItemDelegate(parent),
|
||||
parentWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StarWidgetsDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
QVariant value = index.model()->data(index, TreeItemDT::STAR_ROLE);
|
||||
|
||||
if (!value.isValid())
|
||||
return;
|
||||
|
||||
int rating = value.toInt();
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
for(int i = 0; i < rating; i++)
|
||||
painter->drawPixmap(option.rect.x() + i * IMG_SIZE + SPACING, option.rect.y(), StarWidget::starActive());
|
||||
|
||||
for(int i = rating; i < TOTALSTARS; i++)
|
||||
painter->drawPixmap(option.rect.x() + i * IMG_SIZE + SPACING, option.rect.y(), StarWidget::starInactive());
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize StarWidgetsDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
return QSize(IMG_SIZE * TOTALSTARS + SPACING * (TOTALSTARS-1), IMG_SIZE);
|
||||
}
|
15
qt-ui/modeldelegates.h
Normal file
15
qt-ui/modeldelegates.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef MODELDELEGATES_H
|
||||
#define MODELDELEGATES_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
class StarWidgetsDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit StarWidgetsDelegate(QWidget* parent = 0);
|
||||
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
private:
|
||||
QWidget *parentWidget;
|
||||
};
|
||||
#endif
|
705
qt-ui/models.cpp
Normal file
705
qt-ui/models.cpp
Normal file
|
@ -0,0 +1,705 @@
|
|||
/*
|
||||
* models.cpp
|
||||
*
|
||||
* classes for the equipment models of Subsurface
|
||||
*
|
||||
*/
|
||||
#include "models.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QColor>
|
||||
#include <QBrush>
|
||||
|
||||
extern struct tank_info tank_info[100];
|
||||
|
||||
CylindersModel::CylindersModel(QObject* parent): QAbstractTableModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant CylindersModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
QVariant ret;
|
||||
if (orientation == Qt::Vertical)
|
||||
return ret;
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch(section) {
|
||||
case TYPE:
|
||||
ret = tr("Type");
|
||||
break;
|
||||
case SIZE:
|
||||
ret = tr("Size");
|
||||
break;
|
||||
case MAXPRESS:
|
||||
ret = tr("MaxPress");
|
||||
break;
|
||||
case START:
|
||||
ret = tr("Start");
|
||||
break;
|
||||
case END:
|
||||
ret = tr("End");
|
||||
break;
|
||||
case O2:
|
||||
ret = tr("O2%");
|
||||
break;
|
||||
case HE:
|
||||
ret = tr("He%");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CylindersModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
QVariant CylindersModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
QVariant ret;
|
||||
if (!index.isValid() || index.row() >= MAX_CYLINDERS)
|
||||
return ret;
|
||||
|
||||
cylinder_t& cyl = current_dive->cylinder[index.row()];
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch(index.column()) {
|
||||
case TYPE:
|
||||
ret = QString(cyl.type.description);
|
||||
break;
|
||||
case SIZE:
|
||||
ret = cyl.type.size.mliter;
|
||||
break;
|
||||
case MAXPRESS:
|
||||
ret = cyl.type.workingpressure.mbar;
|
||||
break;
|
||||
case START:
|
||||
ret = cyl.start.mbar;
|
||||
break;
|
||||
case END:
|
||||
ret = cyl.end.mbar;
|
||||
break;
|
||||
case O2:
|
||||
ret = cyl.gasmix.o2.permille;
|
||||
break;
|
||||
case HE:
|
||||
ret = cyl.gasmix.he.permille;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CylindersModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return usedRows[current_dive];
|
||||
}
|
||||
|
||||
void CylindersModel::add(cylinder_t* cyl)
|
||||
{
|
||||
if (usedRows[current_dive] >= MAX_CYLINDERS) {
|
||||
free(cyl);
|
||||
return;
|
||||
}
|
||||
|
||||
int row = usedRows[current_dive];
|
||||
|
||||
cylinder_t& cylinder = current_dive->cylinder[row];
|
||||
|
||||
cylinder.end.mbar = cyl->end.mbar;
|
||||
cylinder.start.mbar = cyl->start.mbar;
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
usedRows[current_dive]++;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void CylindersModel::update()
|
||||
{
|
||||
if (usedRows[current_dive] > 0) {
|
||||
beginRemoveRows(QModelIndex(), 0, usedRows[current_dive]-1);
|
||||
endRemoveRows();
|
||||
}
|
||||
if (usedRows[current_dive] > 0) {
|
||||
beginInsertRows(QModelIndex(), 0, usedRows[current_dive]-1);
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
void CylindersModel::clear()
|
||||
{
|
||||
if (usedRows[current_dive] > 0) {
|
||||
beginRemoveRows(QModelIndex(), 0, usedRows[current_dive]-1);
|
||||
usedRows[current_dive] = 0;
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
|
||||
void WeightModel::clear()
|
||||
{
|
||||
if (usedRows[current_dive] > 0) {
|
||||
beginRemoveRows(QModelIndex(), 0, usedRows[current_dive]-1);
|
||||
usedRows[current_dive] = 0;
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
|
||||
int WeightModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant WeightModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
QVariant ret;
|
||||
if (!index.isValid() || index.row() >= MAX_WEIGHTSYSTEMS)
|
||||
return ret;
|
||||
|
||||
weightsystem_t *ws = ¤t_dive->weightsystem[index.row()];
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch(index.column()) {
|
||||
case TYPE:
|
||||
ret = QString(ws->description);
|
||||
break;
|
||||
case WEIGHT:
|
||||
if (get_units()->weight == units::KG) {
|
||||
int gr = ws->weight.grams % 1000;
|
||||
int kg = ws->weight.grams / 1000;
|
||||
ret = QString("%1.%2").arg(kg).arg((unsigned) gr / 100);
|
||||
} else {
|
||||
ret = QString("%1").arg((unsigned)(grams_to_lbs(ws->weight.grams)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int WeightModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return usedRows[current_dive];
|
||||
}
|
||||
|
||||
QVariant WeightModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
QVariant ret;
|
||||
if (orientation == Qt::Vertical)
|
||||
return ret;
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch(section) {
|
||||
case TYPE:
|
||||
ret = tr("Type");
|
||||
break;
|
||||
case WEIGHT:
|
||||
ret = tr("Weight");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WeightModel::add(weightsystem_t* weight)
|
||||
{
|
||||
if (usedRows[current_dive] >= MAX_WEIGHTSYSTEMS) {
|
||||
free(weight);
|
||||
return;
|
||||
}
|
||||
|
||||
int row = usedRows[current_dive];
|
||||
|
||||
weightsystem_t *ws = ¤t_dive->weightsystem[row];
|
||||
|
||||
ws->description = weight->description;
|
||||
ws->weight.grams = weight->weight.grams;
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
usedRows[current_dive]++;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void WeightModel::update()
|
||||
{
|
||||
}
|
||||
|
||||
void TankInfoModel::add(const QString& description)
|
||||
{
|
||||
// When the user `creates` a new one on the combobox.
|
||||
// for now, empty till dirk cleans the GTK code.
|
||||
}
|
||||
|
||||
void TankInfoModel::clear()
|
||||
{
|
||||
}
|
||||
|
||||
int TankInfoModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
QVariant TankInfoModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
QVariant ret;
|
||||
if (!index.isValid()) {
|
||||
return ret;
|
||||
}
|
||||
struct tank_info *info = &tank_info[index.row()];
|
||||
|
||||
int ml = info->ml;
|
||||
|
||||
int bar = ((info->psi) ? psi_to_bar(info->psi) : info->bar) * 1000 + 0.5;
|
||||
|
||||
if (info->cuft) {
|
||||
double airvolume = cuft_to_l(info->cuft) * 1000.0;
|
||||
ml = airvolume / bar_to_atm(bar) + 0.5;
|
||||
}
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch(index.column()) {
|
||||
case BAR:
|
||||
ret = bar;
|
||||
break;
|
||||
case ML:
|
||||
ret = ml;
|
||||
break;
|
||||
case DESCRIPTION:
|
||||
ret = QString(info->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVariant TankInfoModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
QVariant ret;
|
||||
|
||||
if (orientation != Qt::Horizontal)
|
||||
return ret;
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch(section) {
|
||||
case BAR:
|
||||
ret = tr("Bar");
|
||||
break;
|
||||
case ML:
|
||||
ret = tr("Ml");
|
||||
break;
|
||||
case DESCRIPTION:
|
||||
ret = tr("Description");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int TankInfoModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return rows+1;
|
||||
}
|
||||
|
||||
TankInfoModel::TankInfoModel() : QAbstractTableModel(), rows(-1)
|
||||
{
|
||||
struct tank_info *info = tank_info;
|
||||
for (info = tank_info; info->name; info++, rows++);
|
||||
|
||||
if (rows > -1) {
|
||||
beginInsertRows(QModelIndex(), 0, rows);
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
void TankInfoModel::update()
|
||||
{
|
||||
if(rows > -1) {
|
||||
beginRemoveRows(QModelIndex(), 0, rows);
|
||||
endRemoveRows();
|
||||
}
|
||||
struct tank_info *info = tank_info;
|
||||
for (info = tank_info; info->name; info++, rows++);
|
||||
|
||||
if (rows > -1) {
|
||||
beginInsertRows(QModelIndex(), 0, rows);
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! A DiveItem for use with a DiveTripModel
|
||||
*
|
||||
* A simple class which wraps basic stats for a dive (e.g. duration, depth) and
|
||||
* tidies up after it's children. This is done manually as we don't inherit from
|
||||
* QObject.
|
||||
*
|
||||
*/
|
||||
|
||||
TreeItemDT::~TreeItemDT()
|
||||
{
|
||||
qDeleteAll(children);
|
||||
}
|
||||
|
||||
int TreeItemDT::row() const
|
||||
{
|
||||
if (parent)
|
||||
return parent->children.indexOf(const_cast<TreeItemDT*>(this));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVariant TreeItemDT::data(int column, int role) const
|
||||
{
|
||||
QVariant ret;
|
||||
switch (column) {
|
||||
case NR:
|
||||
ret = tr("#");
|
||||
break;
|
||||
case DATE:
|
||||
ret = tr("Date");
|
||||
break;
|
||||
case RATING:
|
||||
ret = UTF8_BLACKSTAR;
|
||||
break;
|
||||
case DEPTH:
|
||||
ret = (get_units()->length == units::METERS) ? tr("m") : tr("ft");
|
||||
break;
|
||||
case DURATION:
|
||||
ret = tr("min");
|
||||
break;
|
||||
case TEMPERATURE:
|
||||
ret = QString("%1%2").arg(UTF8_DEGREE).arg( (get_units()->temperature == units::CELSIUS) ? "C" : "F");
|
||||
break;
|
||||
case TOTALWEIGHT:
|
||||
ret = (get_units()->weight == units::KG) ? tr("kg") : tr("lbs");
|
||||
break;
|
||||
case SUIT:
|
||||
ret = tr("Suit");
|
||||
break;
|
||||
case CYLINDER:
|
||||
ret = tr("Cyl");
|
||||
break;
|
||||
case NITROX:
|
||||
ret = QString("O%1%").arg(UTF8_SUBSCRIPT_2);
|
||||
break;
|
||||
case SAC:
|
||||
ret = tr("SAC");
|
||||
break;
|
||||
case OTU:
|
||||
ret = tr("OTU");
|
||||
break;
|
||||
case MAXCNS:
|
||||
ret = tr("maxCNS");
|
||||
break;
|
||||
case LOCATION:
|
||||
ret = tr("Location");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct TripItem : public TreeItemDT {
|
||||
virtual QVariant data(int column, int role) const;
|
||||
dive_trip_t* trip;
|
||||
};
|
||||
|
||||
QVariant TripItem::data(int column, int role) const
|
||||
{
|
||||
QVariant ret;
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (column) {
|
||||
case LOCATION:
|
||||
ret = QString(trip->location);
|
||||
break;
|
||||
case DATE:
|
||||
ret = QString(get_trip_date_string(trip->when, trip->nrdives));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct DiveItem : public TreeItemDT {
|
||||
virtual QVariant data(int column, int role) const;
|
||||
struct dive* dive;
|
||||
|
||||
QString displayDuration() const;
|
||||
QString displayDepth() const;
|
||||
QString displayTemperature() const;
|
||||
QString displayWeight() const;
|
||||
QString displaySac() const;
|
||||
int weight() const;
|
||||
};
|
||||
|
||||
QVariant DiveItem::data(int column, int role) const
|
||||
{
|
||||
QVariant retVal;
|
||||
|
||||
switch (role) {
|
||||
case Qt::TextAlignmentRole:
|
||||
switch (column) {
|
||||
case DATE: /* fall through */
|
||||
case SUIT: /* fall through */
|
||||
case LOCATION:
|
||||
retVal = Qt::AlignLeft;
|
||||
break;
|
||||
default:
|
||||
retVal = Qt::AlignRight;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Qt::DisplayRole:
|
||||
switch (column) {
|
||||
case NR:
|
||||
retVal = dive->number;
|
||||
break;
|
||||
case DATE:
|
||||
retVal = QString(get_dive_date_string(dive->when));
|
||||
break;
|
||||
case DEPTH:
|
||||
retVal = displayDepth();
|
||||
break;
|
||||
case DURATION:
|
||||
retVal = displayDuration();
|
||||
break;
|
||||
case TEMPERATURE:
|
||||
retVal = displayTemperature();
|
||||
break;
|
||||
case TOTALWEIGHT:
|
||||
retVal = displayWeight();
|
||||
break;
|
||||
case SUIT:
|
||||
retVal = QString(dive->suit);
|
||||
break;
|
||||
case CYLINDER:
|
||||
retVal = QString(dive->cylinder[0].type.description);
|
||||
break;
|
||||
case NITROX:
|
||||
retVal = QString(get_nitrox_string(dive));
|
||||
break;
|
||||
case SAC:
|
||||
retVal = displaySac();
|
||||
break;
|
||||
case OTU:
|
||||
retVal = dive->otu;
|
||||
break;
|
||||
case MAXCNS:
|
||||
retVal = dive->maxcns;
|
||||
break;
|
||||
case LOCATION:
|
||||
retVal = QString(dive->location);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(role == STAR_ROLE){
|
||||
retVal = dive->rating;
|
||||
}
|
||||
|
||||
if(role == DIVE_ROLE){
|
||||
retVal = QVariant::fromValue<void*>(dive);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
QString DiveItem::displayDepth() const
|
||||
{
|
||||
const int scale = 1000;
|
||||
QString fract, str;
|
||||
if (get_units()->length == units::METERS) {
|
||||
fract = QString::number((unsigned)(dive->maxdepth.mm % scale) / 10);
|
||||
str = QString("%1.%2").arg((unsigned)(dive->maxdepth.mm / scale)).arg(fract, 2, QChar('0'));
|
||||
}
|
||||
if (get_units()->length == units::FEET) {
|
||||
str = QString::number(mm_to_feet(dive->maxdepth.mm),'f',0);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
QString DiveItem::displayDuration() const
|
||||
{
|
||||
int hrs, mins, secs;
|
||||
secs = dive->duration.seconds % 60;
|
||||
mins = dive->duration.seconds / 60;
|
||||
hrs = mins / 60;
|
||||
mins -= hrs * 60;
|
||||
|
||||
QString displayTime;
|
||||
if (hrs)
|
||||
displayTime = QString("%1:%2:").arg(hrs).arg(mins, 2, 10, QChar('0'));
|
||||
else
|
||||
displayTime = QString("%1:").arg(mins);
|
||||
displayTime += QString("%1").arg(secs, 2, 10, QChar('0'));
|
||||
return displayTime;
|
||||
}
|
||||
|
||||
QString DiveItem::displayTemperature() const
|
||||
{
|
||||
QString str;
|
||||
|
||||
if (!dive->watertemp.mkelvin)
|
||||
return str;
|
||||
|
||||
if (get_units()->temperature == units::CELSIUS)
|
||||
str = QString::number(mkelvin_to_C(dive->watertemp.mkelvin), 'f', 1);
|
||||
else
|
||||
str = QString::number(mkelvin_to_F(dive->watertemp.mkelvin), 'f', 1);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
QString DiveItem::displaySac() const
|
||||
{
|
||||
QString str;
|
||||
|
||||
if (get_units()->volume == units::LITER)
|
||||
str = QString::number(dive->sac / 1000, 'f', 1);
|
||||
else
|
||||
str = QString::number(ml_to_cuft(dive->sac), 'f', 2);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
QString DiveItem::displayWeight() const
|
||||
{
|
||||
QString str;
|
||||
|
||||
if (get_units()->weight == units::KG) {
|
||||
int gr = weight() % 1000;
|
||||
int kg = weight() / 1000;
|
||||
str = QString("%1.%2").arg(kg).arg((unsigned)(gr) / 100);
|
||||
} else {
|
||||
str = QString("%1").arg((unsigned)(grams_to_lbs(weight())));
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
int DiveItem::weight() const
|
||||
{
|
||||
weight_t tw = { total_weight(dive) };
|
||||
return tw.grams;
|
||||
}
|
||||
|
||||
|
||||
DiveTripModel::DiveTripModel(QObject* parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
rootItem = new TreeItemDT();
|
||||
setupModelData();
|
||||
}
|
||||
|
||||
DiveTripModel::~DiveTripModel()
|
||||
{
|
||||
delete rootItem;
|
||||
}
|
||||
|
||||
int DiveTripModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return static_cast<TreeItemDT*>(parent.internalPointer())->columnCount();
|
||||
else
|
||||
return rootItem->columnCount();
|
||||
}
|
||||
|
||||
QVariant DiveTripModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
TreeItemDT* item = static_cast<TreeItemDT*>(index.internalPointer());
|
||||
|
||||
return item->data(index.column(), role);
|
||||
}
|
||||
|
||||
Qt::ItemFlags DiveTripModel::flags(const QModelIndex& index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
QVariant DiveTripModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
return rootItem->data(section, role);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex DiveTripModel::index(int row, int column, const QModelIndex& parent)
|
||||
const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
TreeItemDT* parentItem = (!parent.isValid()) ? rootItem : static_cast<TreeItemDT*>(parent.internalPointer());
|
||||
|
||||
TreeItemDT* childItem = parentItem->children[row];
|
||||
|
||||
return (childItem) ? createIndex(row, column, childItem) : QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex DiveTripModel::parent(const QModelIndex& index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
TreeItemDT* childItem = static_cast<TreeItemDT*>(index.internalPointer());
|
||||
TreeItemDT* parentItem = childItem->parent;
|
||||
|
||||
if (parentItem == rootItem || !parentItem)
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentItem->row(), 0, parentItem);
|
||||
}
|
||||
|
||||
int DiveTripModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
TreeItemDT* parentItem;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = rootItem;
|
||||
else
|
||||
parentItem = static_cast<TreeItemDT*>(parent.internalPointer());
|
||||
|
||||
int amount = parentItem->children.count();
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
void DiveTripModel::setupModelData()
|
||||
{
|
||||
int i = dive_table.nr;
|
||||
|
||||
while (--i >= 0) {
|
||||
struct dive* dive = get_dive(i);
|
||||
update_cylinder_related_info(dive);
|
||||
dive_trip_t* trip = dive->divetrip;
|
||||
|
||||
DiveItem* diveItem = new DiveItem();
|
||||
diveItem->dive = dive;
|
||||
|
||||
if (!trip) {
|
||||
diveItem->parent = rootItem;
|
||||
rootItem->children.push_back(diveItem);
|
||||
continue;
|
||||
}
|
||||
if (!trips.keys().contains(trip)) {
|
||||
TripItem* tripItem = new TripItem();
|
||||
tripItem->trip = trip;
|
||||
tripItem->parent = rootItem;
|
||||
tripItem->children.push_back(diveItem);
|
||||
trips[trip] = tripItem;
|
||||
rootItem->children.push_back(tripItem);
|
||||
continue;
|
||||
}
|
||||
TripItem* tripItem = trips[trip];
|
||||
tripItem->children.push_back(diveItem);
|
||||
}
|
||||
}
|
126
qt-ui/models.h
Normal file
126
qt-ui/models.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* models.h
|
||||
*
|
||||
* header file for the equipment models of Subsurface
|
||||
*
|
||||
*/
|
||||
#ifndef MODELS_H
|
||||
#define MODELS_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "../dive.h"
|
||||
#include "../divelist.h"
|
||||
|
||||
/* Encapsulates the tank_info global variable
|
||||
* to show on Qt's Model View System.*/
|
||||
class TankInfoModel : public QAbstractTableModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Column { DESCRIPTION, ML, BAR};
|
||||
TankInfoModel();
|
||||
|
||||
/*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
/*reimp*/ int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
/*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||
/*reimp*/ int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
|
||||
void add(const QString& description);
|
||||
void clear();
|
||||
void update();
|
||||
private:
|
||||
int rows;
|
||||
};
|
||||
|
||||
/* Encapsulation of the Cylinder Model, that presents the
|
||||
* Current cylinders that are used on a dive. */
|
||||
class CylindersModel : public QAbstractTableModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Column {TYPE, SIZE, MAXPRESS, START, END, O2, HE};
|
||||
|
||||
explicit CylindersModel(QObject* parent = 0);
|
||||
/*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
/*reimp*/ int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
/*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||
/*reimp*/ int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
|
||||
void add(cylinder_t *cyl);
|
||||
void clear();
|
||||
void update();
|
||||
private:
|
||||
/* Since the dive doesn't stores the number of cylinders that
|
||||
* it has (max 8) and since I don't want to make a
|
||||
* model-for-each-dive, let's hack this here instead. */
|
||||
QMap<struct dive *, int> usedRows;
|
||||
};
|
||||
|
||||
/* Encapsulation of the Weight Model, that represents
|
||||
* the current weights on a dive. */
|
||||
class WeightModel : public QAbstractTableModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Column {TYPE, WEIGHT};
|
||||
/*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
/*reimp*/ int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
/*reimp*/ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||
/*reimp*/ int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
|
||||
void add(weightsystem_t *weight);
|
||||
void clear();
|
||||
void update();
|
||||
private:
|
||||
/* Remember the number of rows in a dive */
|
||||
QMap<struct dive *, int> usedRows;
|
||||
};
|
||||
|
||||
/*! An AbstractItemModel for recording dive trip information such as a list of dives.
|
||||
*
|
||||
*/
|
||||
|
||||
struct TreeItemDT {
|
||||
Q_DECLARE_TR_FUNCTIONS ( TreeItemDT );
|
||||
public:
|
||||
enum Column {NR, DATE, RATING, DEPTH, DURATION, TEMPERATURE, TOTALWEIGHT,
|
||||
SUIT, CYLINDER, NITROX, SAC, OTU, MAXCNS, LOCATION, DIVE, COLUMNS };
|
||||
|
||||
enum ExtraRoles{STAR_ROLE = Qt::UserRole + 1, DIVE_ROLE};
|
||||
|
||||
virtual ~TreeItemDT();
|
||||
int columnCount() const {
|
||||
return COLUMNS;
|
||||
};
|
||||
|
||||
virtual QVariant data ( int column, int role ) const;
|
||||
int row() const;
|
||||
QList<TreeItemDT *> children;
|
||||
TreeItemDT *parent;
|
||||
};
|
||||
|
||||
struct TripItem;
|
||||
|
||||
class DiveTripModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DiveTripModel(QObject *parent = 0);
|
||||
~DiveTripModel();
|
||||
|
||||
/*reimp*/ Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
/*reimp*/ QVariant data(const QModelIndex &index, int role) const;
|
||||
/*reimp*/ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
/*reimp*/ int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
/*reimp*/ int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
/*reimp*/ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
/*reimp*/ QModelIndex parent(const QModelIndex &child) const;
|
||||
|
||||
private:
|
||||
void setupModelData();
|
||||
|
||||
TreeItemDT *rootItem;
|
||||
QMap<dive_trip_t*, TripItem*> trips;
|
||||
};
|
||||
|
||||
#endif
|
6
qt-ui/plotareascene.cpp
Normal file
6
qt-ui/plotareascene.cpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
/*
|
||||
* plotareascene.cpp
|
||||
*
|
||||
* classes for profile plot area scene of Subsurface
|
||||
*
|
||||
*/
|
6
qt-ui/plotareascene.h
Normal file
6
qt-ui/plotareascene.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
/*
|
||||
* plotareascene.h
|
||||
*
|
||||
* header file for the profile plot area scene of Subsurface
|
||||
*
|
||||
*/
|
1397
qt-ui/profilegraphics.cpp
Normal file
1397
qt-ui/profilegraphics.cpp
Normal file
File diff suppressed because it is too large
Load diff
110
qt-ui/profilegraphics.h
Normal file
110
qt-ui/profilegraphics.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
#ifndef PROFILEGRAPHICS_H
|
||||
#define PROFILEGRAPHICS_H
|
||||
|
||||
#include "../display.h"
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsItem>
|
||||
#include <QIcon>
|
||||
|
||||
struct text_render_options;
|
||||
struct graphics_context;
|
||||
struct plot_info;
|
||||
typedef struct text_render_options text_render_options_t;
|
||||
|
||||
/* To use a tooltip, simply ->setToolTip on the QGraphicsItem that you want
|
||||
* or, if it's a "global" tooltip, set it on the mouseMoveEvent of the ProfileGraphicsView.
|
||||
*/
|
||||
class ToolTipItem :public QObject, public QGraphicsPathItem
|
||||
{
|
||||
Q_OBJECT
|
||||
void updateTitlePosition();
|
||||
Q_PROPERTY(QRectF rect READ boundingRect WRITE setRect)
|
||||
|
||||
public:
|
||||
enum Status{COLLAPSED, EXPANDED};
|
||||
enum {ICON_SMALL = 16, ICON_MEDIUM = 24, ICON_BIG = 32, SPACING=4};
|
||||
|
||||
explicit ToolTipItem(QGraphicsItem* parent = 0);
|
||||
|
||||
void collapse();
|
||||
void expand();
|
||||
void clear();
|
||||
void addToolTip(const QString& toolTip, const QIcon& icon = QIcon());
|
||||
void removeToolTip(const QString& toolTip);
|
||||
void refresh(struct graphics_context* gc, QPointF pos);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setRect(const QRectF& rect);
|
||||
|
||||
private:
|
||||
typedef QPair<QGraphicsPixmapItem*, QGraphicsSimpleTextItem*> ToolTip;
|
||||
QMap<QString, ToolTip > toolTips;
|
||||
QGraphicsPathItem *background;
|
||||
QGraphicsLineItem *separator;
|
||||
QGraphicsSimpleTextItem *title;
|
||||
|
||||
QRectF rectangle;
|
||||
};
|
||||
|
||||
class EventItem : public QGraphicsPolygonItem
|
||||
{
|
||||
public:
|
||||
explicit EventItem(QGraphicsItem* parent = 0);
|
||||
|
||||
private:
|
||||
ToolTipItem *controller;
|
||||
QString text;
|
||||
QIcon icon;
|
||||
};
|
||||
|
||||
class ProfileGraphicsView : public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProfileGraphicsView(QWidget* parent = 0);
|
||||
void plot(struct dive *d);
|
||||
bool eventFilter(QObject* obj, QEvent* event);
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
void showEvent(QShowEvent* event);
|
||||
|
||||
private:
|
||||
void plot_depth_profile();
|
||||
QGraphicsSimpleTextItem* plot_text(text_render_options_t *tro, const QPointF& pos, const QString &text, QGraphicsItem *parent = 0);
|
||||
void plot_events(struct divecomputer *dc);
|
||||
void plot_one_event(struct event *event);
|
||||
void plot_temperature_profile();
|
||||
void plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc);
|
||||
void plot_temperature_text();
|
||||
void plot_single_temp_text(int sec, int mkelvin);
|
||||
void plot_depth_text();
|
||||
void plot_text_samples();
|
||||
void plot_depth_sample(struct plot_data *entry, text_render_options_t *tro);
|
||||
void plot_cylinder_pressure_text();
|
||||
void plot_pressure_value(int mbar, int sec, double xalign, double yalign);
|
||||
void plot_deco_text();
|
||||
void plot_pp_gas_profile();
|
||||
void plot_pp_text();
|
||||
void plot_depth_scale();
|
||||
|
||||
QColor get_sac_color(int sac, int avg_sac);
|
||||
|
||||
QPen defaultPen;
|
||||
QBrush defaultBrush;
|
||||
ToolTipItem *toolTip;
|
||||
graphics_context gc;
|
||||
struct dive *dive;
|
||||
int zoomLevel;
|
||||
|
||||
// Top Level Items.
|
||||
QGraphicsItem* profileGrid;
|
||||
QGraphicsItem* timeMarkers;
|
||||
QGraphicsItem* depthMarkers;
|
||||
QGraphicsItem* diveComputer;
|
||||
};
|
||||
|
||||
#endif
|
100
qt-ui/starwidget.cpp
Normal file
100
qt-ui/starwidget.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "starwidget.h"
|
||||
#include <QSvgRenderer>
|
||||
#include <QPainter>
|
||||
#include <QPaintEvent>
|
||||
#include <QDebug>
|
||||
#include <QMouseEvent>
|
||||
|
||||
QPixmap* StarWidget::activeStar = 0;
|
||||
QPixmap* StarWidget::inactiveStar = 0;
|
||||
|
||||
QPixmap StarWidget::starActive()
|
||||
{
|
||||
return (*activeStar);
|
||||
}
|
||||
|
||||
QPixmap StarWidget::starInactive()
|
||||
{
|
||||
return (*inactiveStar);
|
||||
}
|
||||
|
||||
int StarWidget::currentStars() const
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
void StarWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
int starClicked = event->pos().x() / IMG_SIZE + 1;
|
||||
if (starClicked > TOTALSTARS)
|
||||
starClicked = TOTALSTARS;
|
||||
|
||||
if (current == starClicked)
|
||||
current -= 1;
|
||||
else
|
||||
current = starClicked;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void StarWidget::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QPainter p(this);
|
||||
|
||||
for(int i = 0; i < current; i++)
|
||||
p.drawPixmap(i * IMG_SIZE + SPACING, 0, starActive());
|
||||
|
||||
for(int i = current; i < TOTALSTARS; i++)
|
||||
p.drawPixmap(i * IMG_SIZE + SPACING, 0, starInactive());
|
||||
}
|
||||
|
||||
void StarWidget::setCurrentStars(int value)
|
||||
{
|
||||
current = value;
|
||||
update();
|
||||
Q_EMIT valueChanged(current);
|
||||
}
|
||||
|
||||
StarWidget::StarWidget(QWidget* parent, Qt::WindowFlags f):
|
||||
QWidget(parent, f),
|
||||
current(0)
|
||||
{
|
||||
if(!activeStar){
|
||||
activeStar = new QPixmap();
|
||||
QSvgRenderer render(QString(":star"));
|
||||
QPixmap renderedStar(IMG_SIZE, IMG_SIZE);
|
||||
|
||||
renderedStar.fill(Qt::transparent);
|
||||
QPainter painter(&renderedStar);
|
||||
|
||||
render.render(&painter, QRectF(0, 0, IMG_SIZE, IMG_SIZE));
|
||||
(*activeStar) = renderedStar;
|
||||
}
|
||||
if(!inactiveStar){
|
||||
inactiveStar = new QPixmap();
|
||||
(*inactiveStar) = grayImage(activeStar);
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap StarWidget::grayImage(QPixmap* coloredImg)
|
||||
{
|
||||
QImage img = coloredImg->toImage();
|
||||
for (int i = 0; i < img.width(); ++i) {
|
||||
for (int j = 0; j < img.height(); ++j) {
|
||||
QRgb rgb = img.pixel(i, j);
|
||||
if (!rgb)
|
||||
continue;
|
||||
|
||||
QColor c(rgb);
|
||||
int gray = (c.red() + c.green() + c.blue()) / 3;
|
||||
img.setPixel(i, j, qRgb(gray, gray, gray));
|
||||
}
|
||||
}
|
||||
|
||||
return QPixmap::fromImage(img);
|
||||
}
|
||||
|
||||
QSize StarWidget::sizeHint() const
|
||||
{
|
||||
return QSize(IMG_SIZE * TOTALSTARS + SPACING * (TOTALSTARS-1), IMG_SIZE);
|
||||
}
|
37
qt-ui/starwidget.h
Normal file
37
qt-ui/starwidget.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef STARWIDGET_H
|
||||
#define STARWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
enum StarConfig {SPACING = 2, IMG_SIZE = 16, TOTALSTARS = 5};
|
||||
|
||||
class StarWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit StarWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||
int currentStars() const;
|
||||
|
||||
/*reimp*/ QSize sizeHint() const;
|
||||
|
||||
static QPixmap starActive();
|
||||
static QPixmap starInactive();
|
||||
|
||||
Q_SIGNALS:
|
||||
void valueChanged(int stars);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setCurrentStars(int value);
|
||||
|
||||
protected:
|
||||
/*reimp*/ void mouseReleaseEvent(QMouseEvent* );
|
||||
/*reimp*/ void paintEvent(QPaintEvent* );
|
||||
|
||||
private:
|
||||
int current;
|
||||
static QPixmap* activeStar;
|
||||
static QPixmap* inactiveStar;
|
||||
QPixmap grayImage(QPixmap *coloredImg);
|
||||
};
|
||||
|
||||
#endif // STARWIDGET_H
|
74
star.svg
Normal file
74
star.svg
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32px"
|
||||
height="32px"
|
||||
id="svg15725"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="New document 4">
|
||||
<defs
|
||||
id="defs15727" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.197802"
|
||||
inkscape:cx="16"
|
||||
inkscape:cy="16.044652"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:window-width="1884"
|
||||
inkscape:window-height="1058"
|
||||
inkscape:window-x="-5"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata15730">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#ffff00;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path15735"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="15.628067"
|
||||
sodipodi:cy="15.74681"
|
||||
sodipodi:r1="16.150806"
|
||||
sodipodi:r2="7.9237795"
|
||||
sodipodi:arg1="2.5689263"
|
||||
sodipodi:arg2="3.1972448"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="M 2.0539742,24.498527 7.716555,15.306062 3.110064,5.5415099 13.602452,8.0863163 21.465608,0.68787049 22.28768,11.453112 l 9.466189,5.192062 -9.984319,4.108479 -2.012731,10.607316 -6.99272,-8.226063 z"
|
||||
inkscape:transform-center-x="0.46164082"
|
||||
inkscape:transform-center-y="-1.2197792"
|
||||
transform="matrix(0.86268816,-0.34553411,0.34553411,0.86268816,-2.9571926,8.9732054)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
18
statistics.c
18
statistics.c
|
@ -28,8 +28,6 @@ stats_t stats_selection;
|
|||
stats_t *stats_monthly = NULL;
|
||||
stats_t *stats_yearly = NULL;
|
||||
|
||||
|
||||
|
||||
static void process_temperatures(struct dive *dp, stats_t *stats)
|
||||
{
|
||||
int min_temp, mean_temp, max_temp = 0;
|
||||
|
@ -275,3 +273,19 @@ void get_selected_dives_text(char *buffer, int size)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
volume_t get_gas_used(struct dive *dive)
|
||||
{
|
||||
int idx;
|
||||
volume_t gas_used = { 0 };
|
||||
for (idx = 0; idx < MAX_CYLINDERS; idx++) {
|
||||
cylinder_t *cyl = &dive->cylinder[idx];
|
||||
pressure_t start, end;
|
||||
|
||||
start = cyl->start.mbar ? cyl->start : cyl->sample_start;
|
||||
end = cyl->end.mbar ?cyl->sample_end : cyl->sample_end;
|
||||
if (start.mbar && end.mbar)
|
||||
gas_used.mliter += gas_volume(cyl, start) - gas_volume(cyl, end);
|
||||
}
|
||||
return gas_used;
|
||||
}
|
||||
|
|
15
statistics.h
15
statistics.h
|
@ -4,6 +4,14 @@
|
|||
* core logic functions called from statistics UI
|
||||
* common types and variables
|
||||
*/
|
||||
|
||||
#ifndef STATISTICS_H
|
||||
#define STATISTICS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int period;
|
||||
duration_t total_time;
|
||||
|
@ -31,3 +39,10 @@ extern char *get_time_string(int seconds, int maxdays);
|
|||
extern char *get_minutes(int seconds);
|
||||
extern void process_all_dives(struct dive *dive, struct dive **prev_dive);
|
||||
extern void get_selected_dives_text(char *buffer, int size);
|
||||
extern volume_t get_gas_used(struct dive *dive);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
6
subsurface.qrc
Normal file
6
subsurface.qrc
Normal file
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file alias="star">star.svg</file>
|
||||
<file alias="subsurface-icon">subsurface-icon.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -922,14 +922,18 @@ GError *uemis_download(const char *mountpath, progressbar_t *progress,
|
|||
if (!import_thread_cancelled) {
|
||||
int result;
|
||||
g_timeout_add(100, timeout_func, dialog);
|
||||
#if USE_GTK_UI
|
||||
update_progressbar(args.progress, progress_bar_fraction);
|
||||
update_progressbar_text(args.progress, progress_bar_text);
|
||||
#endif
|
||||
result = gtk_dialog_run(dialog);
|
||||
if (result == GTK_RESPONSE_CANCEL)
|
||||
import_thread_cancelled = TRUE;
|
||||
} else {
|
||||
#if USE_GTK_UI
|
||||
update_progressbar(args.progress, progress_bar_fraction);
|
||||
update_progressbar_text(args.progress, _("Cancelled, exiting cleanly..."));
|
||||
#endif
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,7 +164,9 @@ static void download_dialog_response_cb(GtkDialog *d, gint response, gpointer da
|
|||
/* now merge the data in the gps_location table into the dive_table */
|
||||
if (merge_locations_into_dives()) {
|
||||
mark_divelist_changed(TRUE);
|
||||
#if USE_GTK_UI
|
||||
dive_list_update_dives();
|
||||
#endif
|
||||
}
|
||||
/* store last entered uid in config */
|
||||
subsurface_set_conf("webservice_uid", gtk_entry_get_text(GTK_ENTRY(state->uid)));
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void webservice_download_dialog(void);
|
||||
extern gboolean webservice_request_user_xml(const gchar *, gchar **, guint *, guint *);
|
||||
extern int divelogde_upload(char *fn, char **error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
21
windows.c
21
windows.c
|
@ -1,7 +1,10 @@
|
|||
/* windows.c */
|
||||
/* implements Windows specific functions */
|
||||
#include "dive.h"
|
||||
#include "display.h"
|
||||
#if USE_GTK_UI
|
||||
#include "display-gtk.h"
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
|
@ -20,12 +23,12 @@ void subsurface_open_conf(void)
|
|||
printf("CreateKey Software\\subsurface failed %ld\n", success);
|
||||
}
|
||||
|
||||
void subsurface_unset_conf(char *name)
|
||||
void subsurface_unset_conf(const char *name)
|
||||
{
|
||||
RegDeleteValue(hkey, (LPCTSTR)name);
|
||||
}
|
||||
|
||||
void subsurface_set_conf(char *name, const char *value)
|
||||
void subsurface_set_conf(const char *name, const char *value)
|
||||
{
|
||||
/* since we are using the pointer 'value' as both an actual
|
||||
* pointer to the string setting and as a way to pass the
|
||||
|
@ -52,17 +55,17 @@ void subsurface_set_conf(char *name, const char *value)
|
|||
free(wname);
|
||||
}
|
||||
|
||||
void subsurface_set_conf_int(char *name, int value)
|
||||
void subsurface_set_conf_int(const char *name, int value)
|
||||
{
|
||||
RegSetValueEx(hkey, (LPCTSTR)name, 0, REG_DWORD, (const BYTE *)&value, 4);
|
||||
}
|
||||
|
||||
void subsurface_set_conf_bool(char *name, int value)
|
||||
void subsurface_set_conf_bool(const char *name, int value)
|
||||
{
|
||||
subsurface_set_conf_int(name, value);
|
||||
}
|
||||
|
||||
const void *subsurface_get_conf(char *name)
|
||||
const char *subsurface_get_conf(const char *name)
|
||||
{
|
||||
const int csize = 64;
|
||||
int blen = 0;
|
||||
|
@ -100,7 +103,7 @@ const void *subsurface_get_conf(char *name)
|
|||
return utf8_string;
|
||||
}
|
||||
|
||||
int subsurface_get_conf_int(char *name)
|
||||
int subsurface_get_conf_int(const char *name)
|
||||
{
|
||||
DWORD value = -1, len = 4;
|
||||
LONG ret = RegQueryValueEx(hkey, (LPCTSTR)TEXT(name), NULL, NULL,
|
||||
|
@ -110,7 +113,7 @@ int subsurface_get_conf_int(char *name)
|
|||
return value;
|
||||
}
|
||||
|
||||
int subsurface_get_conf_bool(char *name)
|
||||
int subsurface_get_conf_bool(const char *name)
|
||||
{
|
||||
int ret = subsurface_get_conf_int(name);
|
||||
if (ret == -1)
|
||||
|
@ -128,6 +131,7 @@ void subsurface_close_conf(void)
|
|||
RegCloseKey(hkey);
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
int subsurface_fill_device_list(GtkListStore *store)
|
||||
{
|
||||
const int bufdef = 512;
|
||||
|
@ -194,6 +198,7 @@ int subsurface_fill_device_list(GtkListStore *store)
|
|||
}
|
||||
return index;
|
||||
}
|
||||
#endif /* USE_GTK_UI */
|
||||
|
||||
const char *subsurface_icon_name()
|
||||
{
|
||||
|
@ -231,11 +236,13 @@ const char *subsurface_gettext_domainpath(char *argv0)
|
|||
return "./share/locale";
|
||||
}
|
||||
|
||||
#if USE_GTK_UI
|
||||
void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar,
|
||||
GtkWidget *vbox, GtkUIManager *ui_manager)
|
||||
{
|
||||
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
|
||||
}
|
||||
#endif /* USE_GTK_UI */
|
||||
|
||||
/* barely documented API */
|
||||
extern int __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *);
|
||||
|
|
Loading…
Reference in a new issue