summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-format2
-rw-r--r--CMakeLists.txt1
-rw-r--r--ReleaseNotes.txt2
-rw-r--r--android.cpp7
-rw-r--r--display.h7
-rw-r--r--dive.c47
-rw-r--r--dive.h44
-rw-r--r--divecomputer.cpp17
-rw-r--r--divecomputer.h12
-rw-r--r--divelist.c85
-rw-r--r--divelist.h8
-rw-r--r--linux.c120
-rw-r--r--load-git.c10
-rw-r--r--macos.c67
-rw-r--r--main.cpp2
-rw-r--r--profile.c3
-rw-r--r--profile.h1
-rw-r--r--qt-gui.cpp32
-rw-r--r--qt-ui/completionmodels.cpp6
-rw-r--r--qt-ui/divelistview.cpp256
-rw-r--r--qt-ui/divelistview.h6
-rw-r--r--qt-ui/divelogexportdialog.cpp98
-rw-r--r--qt-ui/divelogexportdialog.h28
-rw-r--r--qt-ui/divelogexportdialog.ui283
-rw-r--r--qt-ui/divelogimportdialog.h3
-rw-r--r--qt-ui/diveplanner.cpp841
-rw-r--r--qt-ui/diveplanner.h151
-rw-r--r--qt-ui/downloadfromdivecomputer.cpp34
-rw-r--r--qt-ui/downloadfromdivecomputer.h4
-rw-r--r--qt-ui/exif.cpp29
-rw-r--r--qt-ui/globe.cpp41
-rw-r--r--qt-ui/globe.h9
-rw-r--r--qt-ui/groupedlineedit.cpp20
-rw-r--r--qt-ui/kmessagewidget.cpp20
-rw-r--r--qt-ui/maintab.cpp53
-rw-r--r--qt-ui/maintab.h6
-rw-r--r--qt-ui/mainwindow.cpp93
-rw-r--r--qt-ui/mainwindow.h14
-rw-r--r--qt-ui/mainwindow.ui63
-rw-r--r--qt-ui/modeldelegates.cpp2
-rw-r--r--qt-ui/models.cpp39
-rw-r--r--qt-ui/preferences.cpp2
-rw-r--r--qt-ui/printlayout.cpp10
-rw-r--r--qt-ui/profile/animationfunctions.cpp10
-rw-r--r--qt-ui/profile/animationfunctions.h3
-rw-r--r--qt-ui/profile/divecartesianaxis.cpp40
-rw-r--r--qt-ui/profile/divecartesianaxis.h2
-rw-r--r--qt-ui/profile/diveplotdatamodel.cpp2
-rw-r--r--qt-ui/profile/diveprofileitem.cpp39
-rw-r--r--qt-ui/profile/diveprofileitem.h14
-rw-r--r--qt-ui/profile/divetooltipitem.cpp19
-rw-r--r--qt-ui/profile/divetooltipitem.h3
-rw-r--r--qt-ui/profile/profilewidget2.cpp479
-rw-r--r--qt-ui/profile/profilewidget2.h34
-rw-r--r--qt-ui/profile/ruleritem.cpp20
-rw-r--r--qt-ui/profile/ruleritem.h10
-rw-r--r--qt-ui/simplewidgets.cpp24
-rw-r--r--qt-ui/simplewidgets.h6
-rw-r--r--qt-ui/subsurfacewebservices.cpp21
-rw-r--r--qt-ui/subsurfacewebservices.h2
-rw-r--r--qt-ui/tagwidget.cpp18
-rw-r--r--qt-ui/tagwidget.h7
-rw-r--r--qt-ui/updatemanager.cpp5
-rw-r--r--qt-ui/updatemanager.h9
-rw-r--r--qt-ui/usermanual.cpp4
-rw-r--r--qt-ui/usermanual.h3
-rw-r--r--qthelper.cpp46
-rw-r--r--save-git.c13
-rw-r--r--save-xml.c6
-rwxr-xr-xscripts/whitespace.pl19
-rw-r--r--statistics.c12
-rw-r--r--subsurface.pro9
-rw-r--r--subsurfacestartup.c11
-rw-r--r--uemis-downloader.c8
-rw-r--r--units.h2
-rw-r--r--windows.c107
-rw-r--r--worldmap-options.h6
-rw-r--r--worldmap-save.c41
-rw-r--r--worldmap-save.h2
79 files changed, 1844 insertions, 1790 deletions
diff --git a/.clang-format b/.clang-format
index 6b75350e0..092136768 100644
--- a/.clang-format
+++ b/.clang-format
@@ -10,6 +10,7 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: true
ColumnLimit: 0
IndentFunctionDeclarationAfterType: false #personal taste, good for long methods
IndentWidth: 8
+ContinuationIndentWidth: 8
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
SpaceBeforeAssignmentOperators: true
@@ -18,3 +19,4 @@ SpacesInParentheses: false
SpacesBeforeTrailingComments: 1
UseTab: Always
PointerBindsToType: false
+# doesn't work, yet -> ForEachMacros: "Q_FOREACH"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 153f8d628..ef58bbf57 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -136,6 +136,7 @@ SET(SUBSURFACE_INTERFACE
qt-ui/tagwidget.cpp
qt-ui/groupedlineedit.cpp
qt-ui/usermanual.cpp
+ qt-ui/divelogexportdialog.cpp
)
#the profile widget
diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt
index e85957012..00cd5faa8 100644
--- a/ReleaseNotes.txt
+++ b/ReleaseNotes.txt
@@ -43,7 +43,7 @@ New in version 4.1 (compared to Subsurface 4.0.3):
- new and improved profile widget with animations, better info box, and
a new toolbox to turn on and off many of the additional graphs and
information displays
-- improved CVS import and added CVS export
+- improved CSV import and added CSV export
- import of exported log files from Sensus (CSV) and Shearwater Desktop
(XML)
- improved UDDF and divelogs.de support
diff --git a/android.cpp b/android.cpp
index 15de9e65d..93f26730b 100644
--- a/android.cpp
+++ b/android.cpp
@@ -18,8 +18,8 @@ const char *system_default_filename(void)
{
/* Replace this when QtCore/QStandardPaths getExternalStorageDirectory landed */
QAndroidJniObject externalStorage = QAndroidJniObject::callStaticObjectMethod("android/os/Environment", "getExternalStorageDirectory", "()Ljava/io/File;");
- QAndroidJniObject externalStorageAbsolute = externalStorage.callObjectMethod( "getAbsolutePath", "()Ljava/lang/String;" );
- QString system_default_filename = externalStorageAbsolute.toString()+"/subsurface.xml";
+ QAndroidJniObject externalStorageAbsolute = externalStorage.callObjectMethod("getAbsolutePath", "()Ljava/lang/String;");
+ QString system_default_filename = externalStorageAbsolute.toString() + "/subsurface.xml";
QAndroidJniEnvironment env;
if (env->ExceptionCheck()) {
// FIXME: Handle exception here.
@@ -29,7 +29,7 @@ const char *system_default_filename(void)
return strdup(system_default_filename.toUtf8().data());
}
-int enumerate_devices (device_callback_t callback, void *userdata)
+int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
{
/* FIXME: we need to enumerate in some other way on android */
/* qtserialport maybee? */
@@ -77,5 +77,4 @@ void subsurface_console_exit(void)
{
/* NOP */
}
-
}
diff --git a/display.h b/display.h
index 65820f075..08c63da04 100644
--- a/display.h
+++ b/display.h
@@ -55,7 +55,12 @@ extern int is_default_dive_computer_device(const char *);
extern int is_default_dive_computer(const char *, const char *);
typedef void (*device_callback_t)(const char *name, void *userdata);
-int enumerate_devices(device_callback_t callback, void *userdata);
+
+#define DC_TYPE_SERIAL 1
+#define DC_TYPE_UEMIS 2
+#define DC_TYPE_OTHER 3
+
+int enumerate_devices(device_callback_t callback, void *userdata, int dc_type);
extern const char *default_dive_computer_vendor;
extern const char *default_dive_computer_product;
diff --git a/dive.c b/dive.c
index 6edcee7ba..ae07d151a 100644
--- a/dive.c
+++ b/dive.c
@@ -19,6 +19,26 @@ static const char *default_tags[] = {
QT_TRANSLATE_NOOP("gettextFromC", "deco")
};
+void make_first_dc()
+{
+ struct divecomputer *dc = &current_dive->dc;
+ struct divecomputer *newdc = malloc(sizeof(*newdc));
+ struct divecomputer *cur_dc = current_dc; /* needs to be in a local variable so the macro isn't re-executed */
+
+ /* skip the current DC in the linked list */
+ while (dc && dc->next != cur_dc)
+ dc = dc->next;
+ if (!dc) {
+ fprintf(stderr, "data inconsistent: can't find the current DC");
+ return;
+ }
+ dc->next = cur_dc->next;
+ *newdc = current_dive->dc;
+ current_dive->dc = *cur_dc;
+ current_dive->dc.next = newdc;
+ free(cur_dc);
+}
+
void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name)
{
struct event *ev, **p;
@@ -45,6 +65,17 @@ void add_event(struct divecomputer *dc, int time, int type, int flags, int value
remember_event(name);
}
+void remove_event(struct event* event)
+{
+ struct event **ep = &current_dc->events;
+ while (ep && *ep != event)
+ ep = &(*ep)->next;
+ if (ep) {
+ *ep = event->next;
+ free(event);
+ }
+}
+
int get_pressure_units(unsigned int mb, const char **units)
{
int pressure;
@@ -221,6 +252,7 @@ struct dive *alloc_dive(void)
if (!dive)
exit(1);
memset(dive, 0, sizeof(*dive));
+ dive->id = dive_getUniqID(dive);
return dive;
}
@@ -955,7 +987,10 @@ struct dive *fixup_dive(struct dive *dive)
weightsystem_t *ws = dive->weightsystem + i;
add_weightsystem_description(ws);
}
- dive->id = dive_getUniqID(dive);
+ /* we should always have a uniq ID as that gets assigned during alloc_dive(),
+ * but we want to make sure... */
+ if (!dive->id)
+ dive->id = dive_getUniqID(dive);
return dive;
}
@@ -1296,11 +1331,8 @@ static void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, int
static void cylinder_renumber(struct dive *dive, int mapping[])
{
struct divecomputer *dc;
-
- dc = &dive->dc;
- do {
+ for_each_dc(dive, dc)
dc_cylinder_renumber(dive, dc, mapping);
- } while ((dc = dc->next) != NULL);
}
/*
@@ -1905,6 +1937,9 @@ static void interleave_dive_computers(struct divecomputer *res,
if (match) {
merge_events(res, a, match, offset);
merge_samples(res, a, match, offset);
+ /* Use the diveid of the later dive! */
+ if (offset > 0)
+ res->diveid = match->diveid;
} else {
res->sample = a->sample;
res->samples = a->samples;
@@ -2135,7 +2170,7 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer
if (dl) {
/* If we prefer downloaded, do those first, and get rid of "might be same" computers */
join_dive_computers(&res->dc, &dl->dc, &a->dc, 1);
- } else if (offset)
+ } else if (offset && might_be_same_device(&a->dc, &b->dc))
interleave_dive_computers(&res->dc, &a->dc, &b->dc, offset);
else
join_dive_computers(&res->dc, &a->dc, &b->dc, 0);
diff --git a/dive.h b/dive.h
index ac45c299c..50bd2df39 100644
--- a/dive.h
+++ b/dive.h
@@ -26,7 +26,7 @@
static inline int same_string(const char *a, const char *b)
{
- return !strcmp(a ? : "", b ? : "");
+ return !strcmp(a ?: "", b ?: "");
}
#include <libxml/tree.h>
@@ -107,6 +107,12 @@ static inline int interpolate(int a, int b, int part, int whole)
return rint(x / whole);
}
+static inline depth_t gas_mod(struct gasmix *mix, pressure_t po2_limit) {
+ depth_t depth;
+ depth.mm = po2_limit.mbar * 1000 / get_o2(mix) * 10 - 10000;
+ return depth;
+}
+
struct sample {
duration_t time;
depth_t depth;
@@ -364,6 +370,7 @@ struct dive_table {
extern struct dive_table dive_table;
extern int selected_dive;
+extern unsigned int dc_number;
#define current_dive (get_dive(selected_dive))
#define current_dc (get_dive_dc(current_dive, dc_number))
@@ -408,6 +415,8 @@ static inline struct divecomputer *get_dive_dc(struct dive *dive, int nr)
return dc;
}
+extern void make_first_dc(void);
+
/*
* Iterate over each dive, with the first parameter being the index
* iterator variable, and the second one being the dive one.
@@ -429,7 +438,7 @@ static inline struct dive *get_dive_by_uemis_diveid(uint32_t diveid, uint32_t de
int i;
struct dive *dive;
- for_each_dive(i, dive) {
+ for_each_dive (i, dive) {
struct divecomputer *dc = &dive->dc;
do {
if (dc->diveid == diveid && dc->deviceid == deviceid)
@@ -439,17 +448,17 @@ static inline struct dive *get_dive_by_uemis_diveid(uint32_t diveid, uint32_t de
return NULL;
}
-static inline struct dive *get_dive_by_diveid(int id)
+static inline struct dive *get_dive_by_uniq_id(int id)
{
int i;
struct dive *dive = NULL;
- for_each_dive(i, dive) {
+ for_each_dive (i, dive) {
if (dive->id == id)
break;
}
#ifdef DEBUG
- if(dive == NULL){
+ if (dive == NULL) {
fprintf(stderr, "Invalid id %x passed to get_dive_by_diveid, try to fix the code\n", id);
exit(1);
}
@@ -457,6 +466,24 @@ static inline struct dive *get_dive_by_diveid(int id)
return dive;
}
+static inline int get_idx_by_uniq_id(int id)
+{
+ int i;
+ struct dive *dive = NULL;
+
+ for_each_dive (i, dive) {
+ if (dive->id == id)
+ break;
+ }
+#ifdef DEBUG
+ if (dive == NULL) {
+ fprintf(stderr, "Invalid id %x passed to get_dive_by_diveid, try to fix the code\n", id);
+ exit(1);
+ }
+#endif
+ return i;
+}
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -490,7 +517,7 @@ extern int export_dives_xslt(const char *filename, const bool selected, const ch
struct git_oid;
struct git_repository;
-#define dummy_git_repository ((git_repository *) 3ul) /* Random bogus pointer, not NULL */
+#define dummy_git_repository ((git_repository *)3ul) /* Random bogus pointer, not NULL */
extern struct git_repository *is_git_repository(const char *filename, const char **branchp);
extern int git_save_dives(struct git_repository *, const char *, bool select_only);
extern int git_load_dives(struct git_repository *, const char *);
@@ -536,7 +563,7 @@ extern unsigned int dc_airtemp(struct divecomputer *dc);
extern unsigned int dc_watertemp(struct divecomputer *dc);
extern struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer_downloaded);
extern struct dive *try_to_merge(struct dive *a, struct dive *b, bool prefer_downloaded);
-extern void renumber_dives(int nr);
+extern void renumber_dives(int start_nr, bool selected_only);
extern void copy_events(struct dive *s, struct dive *d);
extern void copy_cylinders(struct dive *s, struct dive *d);
extern void copy_samples(struct dive *s, struct dive *d);
@@ -544,6 +571,7 @@ extern void copy_samples(struct dive *s, struct dive *d);
extern void fill_default_cylinder(cylinder_t *cyl);
extern void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int time, int idx);
extern void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name);
+extern void remove_event(struct event *event);
extern void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *mean, int *duration);
extern int get_cylinder_index(struct dive *dive, struct event *ev);
extern int nr_cylinders(struct dive *dive);
@@ -674,7 +702,7 @@ extern double strtod_flags(const char *str, const char **ptr, unsigned int flags
#define ascii_strtod(str, ptr) strtod_flags(str, ptr, STRTOD_ASCII)
extern void set_save_userid_local(short value);
-extern void set_userid(char* user_id);
+extern void set_userid(char *user_id);
#ifdef __cplusplus
}
diff --git a/divecomputer.cpp b/divecomputer.cpp
index 6044f1aa6..f427bd42c 100644
--- a/divecomputer.cpp
+++ b/divecomputer.cpp
@@ -41,7 +41,7 @@ bool DiveComputerNode::changesValues(const DiveComputerNode &b) const
(nickName != b.nickName);
}
-const DiveComputerNode *DiveComputerList::getExact(const QString& m, uint32_t d)
+const DiveComputerNode *DiveComputerList::getExact(const QString &m, uint32_t d)
{
for (QMap<QString, DiveComputerNode>::iterator it = dcMap.find(m); it != dcMap.end() && it.key() == m; ++it)
if (it->deviceId == d)
@@ -49,7 +49,7 @@ const DiveComputerNode *DiveComputerList::getExact(const QString& m, uint32_t d)
return NULL;
}
-const DiveComputerNode *DiveComputerList::get(const QString& m)
+const DiveComputerNode *DiveComputerList::get(const QString &m)
{
QMap<QString, DiveComputerNode>::iterator it = dcMap.find(m);
if (it != dcMap.end())
@@ -57,7 +57,7 @@ const DiveComputerNode *DiveComputerList::get(const QString& m)
return NULL;
}
-void DiveComputerList::addDC(const QString& m, uint32_t d, const QString& n, const QString& s,const QString& f)
+void DiveComputerList::addDC(const QString &m, uint32_t d, const QString &n, const QString &s, const QString &f)
{
if (m.isEmpty() || d == 0)
return;
@@ -79,7 +79,7 @@ void DiveComputerList::addDC(const QString& m, uint32_t d, const QString& n, con
dcMap.insert(m, newNode);
}
-void DiveComputerList::rmDC(const QString& m, uint32_t d)
+void DiveComputerList::rmDC(const QString &m, uint32_t d)
{
const DiveComputerNode *existNode = this->getExact(m, d);
dcMap.remove(m, *existNode);
@@ -96,8 +96,8 @@ extern "C" bool compareDC(const DiveComputerNode &a, const DiveComputerNode &b)
return a.deviceId < b.deviceId;
}
-extern "C" void call_for_each_dc(void *f, void (*callback)(void *, const char *, uint32_t,
- const char *, const char *, const char *))
+extern "C" void call_for_each_dc (void *f, void (*callback)(void *, const char *, uint32_t,
+ const char *, const char *, const char *))
{
QList<DiveComputerNode> values = dcList.dcMap.values();
qSort(values.begin(), values.end(), compareDC);
@@ -162,9 +162,9 @@ extern "C" void set_dc_nickname(struct dive *dive)
if (!dive)
return;
- struct divecomputer *dc = &dive->dc;
+ struct divecomputer *dc;
- while (dc) {
+ for_each_dc (dive, dc) {
if (dc->model && *dc->model && dc->deviceid &&
!dcList.getExact(dc->model, dc->deviceid)) {
// we don't have this one, yet
@@ -181,6 +181,5 @@ extern "C" void set_dc_nickname(struct dive *dive)
dcList.addDC(dc->model, dc->deviceid);
}
}
- dc = dc->next;
}
}
diff --git a/divecomputer.h b/divecomputer.h
index e515a6b06..54752abf7 100644
--- a/divecomputer.h
+++ b/divecomputer.h
@@ -23,12 +23,12 @@ class DiveComputerList {
public:
DiveComputerList();
~DiveComputerList();
- const DiveComputerNode *getExact(const QString& m, uint32_t d);
- const DiveComputerNode *get(const QString& m);
- void addDC(const QString& m, uint32_t d,const QString& n = QString(),const QString& s = QString(), const QString& f = QString());
- void rmDC(const QString& m, uint32_t d);
- DiveComputerNode matchDC(const QString& m, uint32_t d);
- DiveComputerNode matchModel(const QString& m);
+ const DiveComputerNode *getExact(const QString &m, uint32_t d);
+ const DiveComputerNode *get(const QString &m);
+ void addDC(const QString &m, uint32_t d, const QString &n = QString(), const QString &s = QString(), const QString &f = QString());
+ void rmDC(const QString &m, uint32_t d);
+ DiveComputerNode matchDC(const QString &m, uint32_t d);
+ DiveComputerNode matchModel(const QString &m);
QMultiMap<QString, DiveComputerNode> dcMap;
QMultiMap<QString, DiveComputerNode> dcWorkingMap;
};
diff --git a/divelist.c b/divelist.c
index b19971087..ca2e9827f 100644
--- a/divelist.c
+++ b/divelist.c
@@ -115,8 +115,6 @@ void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2low_p)
cylinder_t *cyl = dive->cylinder + i;
int o2 = get_o2(&cyl->gasmix);
int he = get_he(&cyl->gasmix);
- int used = 0;
- int first_gas_explicit = 0;
if (!cyl->used)
continue;
@@ -154,12 +152,9 @@ int total_weight(struct dive *dive)
static int active_o2(struct dive *dive, struct divecomputer *dc, duration_t time)
{
- int o2permille = dive->cylinder[0].gasmix.o2.permille;
+ int o2permille = get_o2(&dive->cylinder[0].gasmix);
struct event *event;
- if (!o2permille)
- o2permille = O2_IN_AIR;
-
for (event = dc->events; event; event = event->next) {
if (event->time.seconds > time.seconds)
break;
@@ -583,6 +578,44 @@ void find_new_trip_start_time(dive_trip_t *trip)
trip->when = when;
}
+/* check if we have a trip right before / after this dive */
+bool is_trip_before_after(struct dive *dive, bool before)
+{
+ int idx = get_idx_by_uniq_id(dive->id);
+ if (before) {
+ if (idx > 0 && get_dive(idx - 1)->divetrip)
+ return true;
+ } else {
+ if (idx < dive_table.nr - 1 && get_dive(idx + 1)->divetrip)
+ return true;
+ }
+ return false;
+}
+
+struct dive *first_selected_dive()
+{
+ int idx;
+ struct dive *d;
+
+ for_each_dive (idx, d) {
+ if (d->selected)
+ return d;
+ }
+ return NULL;
+}
+
+struct dive *last_selected_dive()
+{
+ int idx;
+ struct dive *d, *ret = NULL;
+
+ for_each_dive (idx, d) {
+ if (d->selected)
+ ret = d;
+ }
+ return ret;
+}
+
void remove_dive_from_trip(struct dive *dive, short was_autogen)
{
struct dive *next, **pprev;
@@ -813,6 +846,43 @@ void deselect_dive(int idx)
}
}
+void deselect_dives_in_trip(struct dive_trip *trip)
+{
+ struct dive *dive;
+ if (!trip)
+ return;
+ for (dive = trip->dives; dive; dive = dive->next)
+ deselect_dive(get_divenr(dive));
+}
+
+void select_dives_in_trip(struct dive_trip *trip)
+{
+ struct dive *dive;
+ if (!trip)
+ return;
+ for (dive = trip->dives; dive; dive = dive->next)
+ select_dive(get_divenr(dive));
+}
+
+/* This only gets called with non-NULL trips.
+ * It does not combine notes or location, just picks the first one
+ * (or the second one if the first one is empty */
+void combine_trips(struct dive_trip *trip_a, struct dive_trip *trip_b)
+{
+ if (same_string(trip_a->location, "") && trip_b->location) {
+ free(trip_a->location);
+ trip_a->location = strdup(trip_b->location);
+ }
+ if (same_string(trip_a->notes, "") && trip_b->notes) {
+ free(trip_a->notes);
+ trip_a->notes = strdup(trip_b->notes);
+ }
+ /* this also removes the dives from trip_b and eventually
+ * calls delete_trip(trip_b) when the last dive has been moved */
+ while (trip_b->dives)
+ add_dive_to_trip(trip_b->dives, trip_a);
+}
+
void mark_divelist_changed(int changed)
{
dive_list_changed = changed;
@@ -912,6 +982,9 @@ void process_dives(bool is_imported, bool prefer_imported)
for (i = preexisting; i < dive_table.nr; i++)
set_dc_nickname(dive_table.dives[i]);
+ for (i = preexisting; i < dive_table.nr; i++)
+ dive_table.dives[i]->downloaded = true;
+
/* This does the right thing for -1: NULL */
last = get_dive(preexisting - 1);
diff --git a/divelist.h b/divelist.h
index ade4ce9a6..4eafd5dd4 100644
--- a/divelist.h
+++ b/divelist.h
@@ -30,7 +30,13 @@ extern struct dive *merge_two_dives(struct dive *a, struct dive *b);
extern bool consecutive_selected();
extern void select_dive(int idx);
extern void deselect_dive(int idx);
-void find_new_trip_start_time(dive_trip_t *trip);
+extern void select_dives_in_trip(struct dive_trip *trip);
+extern void deselect_dives_in_trip(struct dive_trip *trip);
+extern void combine_trips(struct dive_trip *trip_a, struct dive_trip *trip_b);
+extern void find_new_trip_start_time(dive_trip_t *trip);
+extern struct dive *first_selected_dive();
+extern struct dive *last_selected_dive();
+extern bool is_trip_before_after(struct dive *dive, bool before);
#ifdef DEBUG_TRIP
extern void dump_selection(void);
diff --git a/linux.c b/linux.c
index 8c79a3f2d..ed063b28c 100644
--- a/linux.c
+++ b/linux.c
@@ -49,78 +49,84 @@ const char *system_default_filename(void)
return buffer;
}
-int enumerate_devices(device_callback_t callback, void *userdata)
+int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
{
- int index = -1;
+ int index = -1, entries = 0;
DIR *dp = NULL;
struct dirent *ep = NULL;
size_t i;
- const char *dirname = "/dev";
- const char *patterns[] = {
- "ttyUSB*",
- "ttyS*",
- "ttyACM*",
- "rfcomm*",
- NULL
- };
FILE *file;
char *line = NULL;
char *fname;
size_t len;
+ if (dc_type != DC_TYPE_UEMIS) {
+ const char *dirname = "/dev";
+ const char *patterns[] = {
+ "ttyUSB*",
+ "ttyS*",
+ "ttyACM*",
+ "rfcomm*",
+ NULL
+ };
+
+ dp = opendir(dirname);
+ if (dp == NULL) {
+ return -1;
+ }
- dp = opendir(dirname);
- if (dp == NULL) {
- return -1;
- }
-
- while ((ep = readdir(dp)) != NULL) {
- for (i = 0; patterns[i] != NULL; ++i) {
- if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
- char filename[1024];
- int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
- if (n >= sizeof(filename)) {
- closedir(dp);
- return -1;
+ while ((ep = readdir(dp)) != NULL) {
+ for (i = 0; patterns[i] != NULL; ++i) {
+ if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
+ char filename[1024];
+ int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
+ if (n >= sizeof(filename)) {
+ closedir(dp);
+ return -1;
+ }
+ callback(filename, userdata);
+ if (is_default_dive_computer_device(filename))
+ index = entries;
+ entries++;
+ break;
}
- callback(filename, userdata);
- if (is_default_dive_computer_device(filename))
- index = i;
- break;
}
}
+ closedir(dp);
}
- closedir(dp);
-
- file = fopen("/proc/mounts", "r");
- if (file == NULL)
- return index;
-
- while ((getline(&line, &len, file)) != -1) {
- char *ptr = strstr(line, "UEMISSDA");
- if (ptr) {
- char *end = ptr, *start = ptr;
- while (start > line && *start != ' ')
- start--;
- if (*start == ' ')
- start++;
- while (*end != ' ' && *end != '\0')
- end++;
-
- *end = '\0';
- fname = strdup(start);
-
- callback(fname, userdata);
-
- if (is_default_dive_computer_device(fname))
- index = i;
- i++;
- free((void *)fname);
+ if (dc_type != DC_TYPE_SERIAL) {
+ int num_uemis = 0;
+ file = fopen("/proc/mounts", "r");
+ if (file == NULL)
+ return index;
+
+ while ((getline(&line, &len, file)) != -1) {
+ char *ptr = strstr(line, "UEMISSDA");
+ if (ptr) {
+ char *end = ptr, *start = ptr;
+ while (start > line && *start != ' ')
+ start--;
+ if (*start == ' ')
+ start++;
+ while (*end != ' ' && *end != '\0')
+ end++;
+
+ *end = '\0';
+ fname = strdup(start);
+
+ callback(fname, userdata);
+
+ if (is_default_dive_computer_device(fname))
+ index = entries;
+ entries++;
+ num_uemis++;
+ free((void *)fname);
+ }
}
+ free(line);
+ fclose(file);
+ if (num_uemis == 1 && entries == 1) /* if we found only one and it's a mounted Uemis, pick it */
+ index = 0;
}
-
- free(line);
- fclose(file);
-
return index;
}
diff --git a/load-git.c b/load-git.c
index c1007358c..acfdd2527 100644
--- a/load-git.c
+++ b/load-git.c
@@ -1115,11 +1115,13 @@ static struct divecomputer *create_new_dc(struct dive *dive)
/* Did we already fill that in? */
if (dc->samples || dc->model || dc->when) {
struct divecomputer *newdc = calloc(1, sizeof(*newdc));
- if (newdc) {
- dc->next = newdc;
- dc = newdc;
- }
+ if (!newdc)
+ return NULL;
+ dc->next = newdc;
+ dc = newdc;
}
+ dc->when = dive->when;
+ dc->duration = dive->duration;
return dc;
}
diff --git a/macos.c b/macos.c
index 25d6fd73f..b75ddbf6f 100644
--- a/macos.c
+++ b/macos.c
@@ -45,27 +45,54 @@ const char *system_default_filename(void)
return buffer;
}
-int enumerate_devices(device_callback_t callback, void *userdata)
+int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
{
- int index = -1;
+ int index = -1, entries = 0;
DIR *dp = NULL;
struct dirent *ep = NULL;
size_t i;
- const char *dirname = "/dev";
- const char *patterns[] = {
- "tty.*",
- "usbserial",
- NULL
- };
-
- dp = opendir(dirname);
- if (dp == NULL) {
- return -1;
+ if (dc_type != DC_TYPE_UEMIS) {
+ const char *dirname = "/dev";
+ const char *patterns[] = {
+ "tty.*",
+ "usbserial",
+ NULL
+ };
+
+ dp = opendir(dirname);
+ if (dp == NULL) {
+ return -1;
+ }
+
+ while ((ep = readdir(dp)) != NULL) {
+ for (i = 0; patterns[i] != NULL; ++i) {
+ if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
+ char filename[1024];
+ int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
+ if (n >= sizeof(filename)) {
+ closedir(dp);
+ return -1;
+ }
+ callback(filename, userdata);
+ if (is_default_dive_computer_device(filename))
+ index = entries;
+ entries++;
+ break;
+ }
+ }
+ }
+ closedir(dp);
}
+ if (dc_type != DC_TYPE_SERIAL) {
+ const char *dirname = "/Volumes";
+ int num_uemis = 0;
+ dp = opendir(dirname);
+ if (dp == NULL) {
+ return -1;
+ }
- while ((ep = readdir(dp)) != NULL) {
- for (i = 0; patterns[i] != NULL; ++i) {
- if (fnmatch(patterns[i], ep->d_name, 0) == 0) {
+ while ((ep = readdir(dp)) != NULL) {
+ if (fnmatch("UEMISSDA", ep->d_name, 0) == 0) {
char filename[1024];
int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name);
if (n >= sizeof(filename)) {
@@ -74,14 +101,16 @@ int enumerate_devices(device_callback_t callback, void *userdata)
}
callback(filename, userdata);
if (is_default_dive_computer_device(filename))
- index = i;
+ index = entries;
+ entries++;
+ num_uemis++;
break;
}
}
+ closedir(dp);
+ if (num_uemis == 1 && entries == 1) /* if we find exactly one entry and that's a Uemis, select it */
+ index = 0;
}
- // TODO: list UEMIS mount point from /proc/mounts
-
- closedir(dp);
return index;
}
diff --git a/main.cpp b/main.cpp
index fd4822324..7adc1f562 100644
--- a/main.cpp
+++ b/main.cpp
@@ -26,7 +26,7 @@ int main(int argc, char **argv)
QStringList arguments = QCoreApplication::arguments();
bool dedicated_console = arguments.length() > 1 &&
- (arguments.at(1) == QString("--win32console"));
+ (arguments.at(1) == QString("--win32console"));
subsurface_console_init(dedicated_console);
for (i = 1; i < arguments.length(); i++) {
diff --git a/profile.c b/profile.c
index fea03308d..26b267dd0 100644
--- a/profile.c
+++ b/profile.c
@@ -1155,7 +1155,8 @@ static void calculate_gas_information_new(struct dive *dive, struct plot_info *p
* so there is no difference in calculating between OC and CC
* END takes O2 + N2 (air) into account ("Narcotic" for trimix dives)
* EAD just uses N2 ("Air" for nitrox dives) */
- entry->mod = (prefs.modppO2 / fo2 * 1000 - 1) * 10000;
+ pressure_t modppO2 = { .mbar = (int) (prefs.modppO2 * 1000) };
+ entry->mod = (double) gas_mod(&dive->cylinder[cylinderindex].gasmix, modppO2).mm;
entry->end = (entry->depth + 10000) * (1000 - fhe) / 1000.0 - 10000;
entry->ead = (entry->depth + 10000) * (1000 - fo2 - fhe) / (double)N2_IN_AIR - 10000;
entry->eadd = (entry->depth + 10000) *
diff --git a/profile.h b/profile.h
index f982d3900..54d250a2b 100644
--- a/profile.h
+++ b/profile.h
@@ -80,7 +80,6 @@ int get_maxtime(struct plot_info *pi);
int get_maxdepth(struct plot_info *pi);
-
#define SENSOR_PR 0
#define INTERPOLATED_PR 1
#define SENSOR_PRESSURE(_entry) (_entry)->pressure[SENSOR_PR]
diff --git a/qt-gui.cpp b/qt-gui.cpp
index 9d6dde45f..f342e20e1 100644
--- a/qt-gui.cpp
+++ b/qt-gui.cpp
@@ -391,12 +391,12 @@ QString get_dive_date_string(timestamp_t when)
struct tm tm;
utc_mkdate(when, &tm);
return translate("gettextFromC", "%1, %2 %3, %4 %5:%6")
- .arg(weekday(tm.tm_wday))
- .arg(monthname(tm.tm_mon))
- .arg(tm.tm_mday)
- .arg(tm.tm_year + 1900)
- .arg(tm.tm_hour, 2, 10, QChar('0'))
- .arg(tm.tm_min, 2, 10, QChar('0'));
+ .arg(weekday(tm.tm_wday))
+ .arg(monthname(tm.tm_mon))
+ .arg(tm.tm_mday)
+ .arg(tm.tm_year + 1900)
+ .arg(tm.tm_hour, 2, 10, QChar('0'))
+ .arg(tm.tm_min, 2, 10, QChar('0'));
}
QString get_short_dive_date_string(timestamp_t when)
@@ -404,11 +404,11 @@ QString get_short_dive_date_string(timestamp_t when)
struct tm tm;
utc_mkdate(when, &tm);
return translate("gettextFromC", "%1 %2, %3\n%4:%5")
- .arg(monthname(tm.tm_mon))
- .arg(tm.tm_mday)
- .arg(tm.tm_year + 1900)
- .arg(tm.tm_hour, 2, 10, QChar('0'))
- .arg(tm.tm_min, 2, 10, QChar('0'));
+ .arg(monthname(tm.tm_mon))
+ .arg(tm.tm_mday)
+ .arg(tm.tm_year + 1900)
+ .arg(tm.tm_hour, 2, 10, QChar('0'))
+ .arg(tm.tm_min, 2, 10, QChar('0'));
}
QString get_trip_date_string(timestamp_t when, int nr)
@@ -417,11 +417,11 @@ QString get_trip_date_string(timestamp_t when, int nr)
utc_mkdate(when, &tm);
if (nr != 1)
return translate("gettextFromC", "%1 %2 (%3 dives)")
- .arg(monthname(tm.tm_mon))
- .arg(tm.tm_year + 1900)
- .arg(nr);
+ .arg(monthname(tm.tm_mon))
+ .arg(tm.tm_year + 1900)
+ .arg(nr);
else
return translate("gettextFromC", "%1 %2 (1 dive)")
- .arg(monthname(tm.tm_mon))
- .arg(tm.tm_year + 1900);
+ .arg(monthname(tm.tm_mon))
+ .arg(tm.tm_year + 1900);
}
diff --git a/qt-ui/completionmodels.cpp b/qt-ui/completionmodels.cpp
index 30e69d26a..7d7f7cd2b 100644
--- a/qt-ui/completionmodels.cpp
+++ b/qt-ui/completionmodels.cpp
@@ -8,7 +8,7 @@
QStringList list; \
struct dive *dive; \
int i = 0; \
- for_each_dive(i, dive) \
+ for_each_dive (i, dive) \
{ \
QString buddy(dive->diveStructMember); \
if (!list.contains(buddy)) { \
@@ -24,10 +24,10 @@
QSet<QString> set; \
struct dive *dive; \
int i = 0; \
- for_each_dive(i, dive) \
+ for_each_dive (i, dive) \
{ \
QString buddy(dive->diveStructMember); \
- foreach(const QString &value, buddy.split(",", QString::SkipEmptyParts)) \
+ foreach (const QString &value, buddy.split(",", QString::SkipEmptyParts)) \
{ \
set.insert(value.trimmed()); \
} \
diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
index 6fd5dee10..cbb75c102 100644
--- a/qt-ui/divelistview.cpp
+++ b/qt-ui/divelistview.cpp
@@ -9,6 +9,7 @@
#include "modeldelegates.h"
#include "mainwindow.h"
#include "subsurfacewebservices.h"
+#include "divelogexportdialog.h"
#include "../display.h"
#include "exif.h"
#include "../file.h"
@@ -27,7 +28,8 @@
#include <iostream>
#include "../qthelper.h"
-DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false), sortColumn(0), currentOrder(Qt::DescendingOrder), searchBox(this)
+DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false), sortColumn(0)
+ , currentOrder(Qt::DescendingOrder), searchBox(this), dontEmitDiveChangedSignal(false)
{
setItemDelegate(new DiveListDelegate(this));
setUniformRowHeights(true);
@@ -57,7 +59,8 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
searchBox.hide();
connect(showSearchBox, SIGNAL(triggered(bool)), this, SLOT(showSearchEdit()));
connect(&searchBox, SIGNAL(textChanged(QString)), model, SLOT(setFilterFixedString(QString)));
- setupUi();
+ // calling setupUi() here appears to be too early; it does NOT correctly set the column widths
+ // setupUi();
}
DiveListView::~DiveListView()
@@ -122,7 +125,7 @@ void DiveListView::backupExpandedRows()
void DiveListView::restoreExpandedRows()
{
setAnimated(false);
- Q_FOREACH(const int & i, expandedRows)
+ Q_FOREACH (const int &i, expandedRows)
setExpanded(model()->index(i, 0), true);
setAnimated(true);
}
@@ -139,7 +142,7 @@ void DiveListView::rememberSelection()
{
selectedDives.clear();
QItemSelection selection = selectionModel()->selection();
- Q_FOREACH(const QModelIndex & index, selection.indexes()) {
+ Q_FOREACH (const QModelIndex &index, selection.indexes()) {
if (index.column() != 0) // We only care about the dives, so, let's stick to rows and discard columns.
continue;
struct dive *d = (struct dive *)index.data(DiveTripModel::DIVE_ROLE).value<void *>();
@@ -151,18 +154,18 @@ void DiveListView::rememberSelection()
void DiveListView::restoreSelection()
{
unselectDives();
- Q_FOREACH(dive_trip_t * trip, selectedDives.keys()) {
+ Q_FOREACH (dive_trip_t *trip, selectedDives.keys()) {
QList<int> divesOnTrip = getDivesInTrip(trip);
QList<int> selectedDivesOnTrip = selectedDives.values(trip);
// Trip was not selected, let's select single-dives.
if (trip == NULL || divesOnTrip.count() != selectedDivesOnTrip.count()) {
- Q_FOREACH(int i, selectedDivesOnTrip) {
+ Q_FOREACH (int i, selectedDivesOnTrip) {
selectDive(i);
}
} else {
selectTrip(trip);
- Q_FOREACH(int i, selectedDivesOnTrip) {
+ Q_FOREACH (int i, selectedDivesOnTrip) {
selectDive(i);
}
}
@@ -189,13 +192,20 @@ void DiveListView::selectTrip(dive_trip_t *trip)
void DiveListView::unselectDives()
{
selectionModel()->clearSelection();
+ // clearSelection should emit selectionChanged() but sometimes that
+ // appears not to happen
+ int i;
+ struct dive *dive;
+ for_each_dive(i, dive) {
+ deselect_dive(i);
+ }
}
QList<dive_trip_t *> DiveListView::selectedTrips()
{
QModelIndexList indexes = selectionModel()->selectedRows();
QList<dive_trip_t *> ret;
- Q_FOREACH(const QModelIndex & index, indexes) {
+ Q_FOREACH (const QModelIndex &index, indexes) {
dive_trip_t *trip = static_cast<dive_trip_t *>(index.data(DiveTripModel::TRIP_ROLE).value<void *>());
if (!trip)
continue;
@@ -211,6 +221,8 @@ void DiveListView::selectDive(int i, bool scrollto, bool toggle)
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
QModelIndexList match = m->match(m->index(0, 0), DiveTripModel::DIVE_IDX, i, 2, Qt::MatchRecursive);
QItemSelectionModel::SelectionFlags flags;
+ if (match.isEmpty())
+ return;
QModelIndex idx = match.first();
flags = toggle ? QItemSelectionModel::Toggle : QItemSelectionModel::Select;
flags |= QItemSelectionModel::Rows;
@@ -231,54 +243,24 @@ void DiveListView::selectDives(const QList<int> &newDiveSelection)
if (!newDiveSelection.count())
return;
- disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
- this, SLOT(selectionChanged(QItemSelection, QItemSelection)));
- disconnect(selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
- this, SLOT(currentChanged(QModelIndex, QModelIndex)));
+ dontEmitDiveChangedSignal = true;
+ // select the dives, highest index first - this way the oldest of the dives
+ // becomes the selected_dive that we scroll to
+ QList<int> sortedSelection = newDiveSelection;
+ qSort(sortedSelection.begin(), sortedSelection.end());
+ while (!sortedSelection.isEmpty())
+ selectDive(sortedSelection.takeLast());
- setAnimated(false);
- collapseAll();
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
- QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::Select | QItemSelectionModel::Rows;
-
- QItemSelection newDeselected = selectionModel()->selection();
- QModelIndexList diveList;
-
- //TODO: This should be called find_first_selected_dive and be ported to C code.
- int firstSelectedDive = -1;
- /* context for temp. variables. */ {
- int i = 0;
- struct dive *dive;
- for_each_dive(i, dive) {
- dive->selected = newDiveSelection.contains(i) == true;
- if (firstSelectedDive == -1 && dive->selected) {
- firstSelectedDive = i;
- break;
- }
- }
- }
- select_dive(firstSelectedDive);
- Q_FOREACH(int i, newDiveSelection) {
- diveList.append(m->match(m->index(0, 0), DiveTripModel::DIVE_IDX,
- i, 2, Qt::MatchRecursive).first());
- }
- Q_FOREACH(const QModelIndex & idx, diveList) {
- selectionModel()->select(idx, flags);
- if (idx.parent().isValid() && !isExpanded(idx.parent())) {
- expand(idx.parent());
- }
- }
- setAnimated(true);
- QTreeView::selectionChanged(selectionModel()->selection(), newDeselected);
- connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
- this, SLOT(selectionChanged(QItemSelection, QItemSelection)));
- connect(selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
- this, SLOT(currentChanged(QModelIndex, QModelIndex)));
- Q_EMIT currentDiveChanged(selected_dive);
QModelIndex idx = m->match(m->index(0, 0), DiveTripModel::DIVE_IDX, selected_dive, 2, Qt::MatchRecursive).first();
if (idx.parent().isValid())
scrollTo(idx.parent());
scrollTo(idx);
+
+ // now that everything is up to date, update the widgets
+ Q_EMIT currentDiveChanged(selected_dive);
+ dontEmitDiveChangedSignal = false;
+ return;
}
void DiveListView::showSearchEdit()
@@ -328,10 +310,19 @@ void DiveListView::headerClicked(int i)
}
}
restoreSelection();
+ // remember the new sort column
+ sortColumn = i;
}
void DiveListView::reload(DiveTripModel::Layout layout, bool forceSort)
{
+ // we want to run setupUi() once we actually are displaying something
+ // in the widget
+ static bool first = true;
+ if (first && dive_table.nr > 0) {
+ setupUi();
+ first = false;
+ }
if (layout == DiveTripModel::CURRENT)
layout = currentLayout;
else
@@ -368,7 +359,6 @@ void DiveListView::reload(DiveTripModel::Layout layout, bool forceSort)
setCurrentIndex(firstDiveOrTrip);
}
}
- setupUi();
if (selectedIndexes().count()) {
QModelIndex curr = selectedIndexes().first();
curr = curr.parent().isValid() ? curr.parent() : curr;
@@ -396,7 +386,7 @@ void DiveListView::reloadHeaderActions()
QString settingName = QString("showColumn%1").arg(i);
QAction *a = new QAction(title, header());
bool showHeaderFirstRun = !(
- i == DiveTripModel::MAXCNS || i == DiveTripModel::NITROX || i == DiveTripModel::OTU || i == DiveTripModel::TEMPERATURE || i == DiveTripModel::TOTALWEIGHT || i == DiveTripModel::SUIT || i == DiveTripModel::CYLINDER || i == DiveTripModel::SAC);
+ i == DiveTripModel::MAXCNS || i == DiveTripModel::NITROX || i == DiveTripModel::OTU || i == DiveTripModel::TEMPERATURE || i == DiveTripModel::TOTALWEIGHT || i == DiveTripModel::SUIT || i == DiveTripModel::CYLINDER || i == DiveTripModel::SAC);
bool shown = s.value(settingName, showHeaderFirstRun).toBool();
a->setCheckable(true);
a->setChecked(shown);
@@ -445,39 +435,26 @@ void DiveListView::selectionChanged(const QItemSelection &selected, const QItemS
disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(selectionChanged(QItemSelection, QItemSelection)));
disconnect(selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex, QModelIndex)));
- Q_FOREACH(const QModelIndex & index, newDeselected.indexes()) {
+ Q_FOREACH (const QModelIndex &index, newDeselected.indexes()) {
if (index.column() != 0)
continue;
const QAbstractItemModel *model = index.model();
struct dive *dive = (struct dive *)model->data(index, DiveTripModel::DIVE_ROLE).value<void *>();
- if (!dive) { // it's a trip!
- //TODO: deselect_trip_dives on c-code?
- if (model->rowCount(index)) {
- struct dive *child = (struct dive *)model->data(index.child(0, 0), DiveTripModel::DIVE_ROLE).value<void *>();
- while (child) {
- deselect_dive(get_divenr(child));
- child = child->next;
- }
- }
- } else {
+ if (!dive) // it's a trip!
+ deselect_dives_in_trip((dive_trip_t *)model->data(index, DiveTripModel::TRIP_ROLE).value<void *>());
+ else
deselect_dive(get_divenr(dive));
- }
}
- Q_FOREACH(const QModelIndex & index, newSelected.indexes()) {
+ Q_FOREACH (const QModelIndex &index, newSelected.indexes()) {
if (index.column() != 0)
continue;
const QAbstractItemModel *model = index.model();
struct dive *dive = (struct dive *)model->data(index, DiveTripModel::DIVE_ROLE).value<void *>();
if (!dive) { // it's a trip!
- //TODO: select_trip_dives on C code?
if (model->rowCount(index)) {
QItemSelection selection;
- struct dive *child = (struct dive *)model->data(index.child(0, 0), DiveTripModel::DIVE_ROLE).value<void *>();
- while (child) {
- select_dive(get_divenr(child));
- child = child->next;
- }
+ select_dives_in_trip((dive_trip_t *)model->data(index, DiveTripModel::TRIP_ROLE).value<void *>());
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);
@@ -491,8 +468,8 @@ void DiveListView::selectionChanged(const QItemSelection &selected, const QItemS
QTreeView::selectionChanged(selectionModel()->selection(), newDeselected);
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(selectionChanged(QItemSelection, QItemSelection)));
connect(selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex, QModelIndex)));
- // now that everything is up to date, update the widgets
- Q_EMIT currentDiveChanged(selected_dive);
+ if(!dontEmitDiveChangedSignal)
+ Q_EMIT currentDiveChanged(selected_dive);
}
static bool can_merge(const struct dive *a, const struct dive *b)
@@ -512,7 +489,7 @@ void DiveListView::mergeDives()
int i;
struct dive *dive, *maindive = NULL;
- for_each_dive(i, dive) {
+ for_each_dive (i, dive) {
if (dive->selected) {
if (!can_merge(maindive, dive)) {
maindive = dive;
@@ -525,6 +502,12 @@ void DiveListView::mergeDives()
MainWindow::instance()->refreshDisplay();
}
+void DiveListView::renumberDives()
+{
+ RenumberDialog::instance()->renumberOnlySelected();
+ RenumberDialog::instance()->show();
+}
+
void DiveListView::merge_trip(const QModelIndex &a, int offset)
{
int i = a.row() + offset;
@@ -532,17 +515,9 @@ void DiveListView::merge_trip(const QModelIndex &a, int offset)
dive_trip_t *trip_a = (dive_trip_t *)a.data(DiveTripModel::TRIP_ROLE).value<void *>();
dive_trip_t *trip_b = (dive_trip_t *)b.data(DiveTripModel::TRIP_ROLE).value<void *>();
- // TODO: merge_trip on the C code? some part of this needs to stay ( getting the trips from the model,
- // but not the algorithm.
if (trip_a == trip_b || !trip_a || !trip_b)
return;
-
- if (!trip_a->location && trip_b->location)
- trip_a->location = strdup(trip_b->location);
- if (!trip_a->notes && trip_b->notes)
- trip_a->notes = strdup(trip_b->notes);
- while (trip_b->dives)
- add_dive_to_trip(trip_b->dives, trip_a);
+ combine_trips(trip_a, trip_b);
rememberSelection();
reload(currentLayout, false);
fixMessyQtModelBehaviour();
@@ -566,7 +541,7 @@ void DiveListView::removeFromTrip()
//TODO: move this to C-code.
int i;
struct dive *d;
- for_each_dive(i, d) {
+ for_each_dive (i, d) {
if (d->selected)
remove_dive_from_trip(d, false);
}
@@ -587,7 +562,7 @@ void DiveListView::newTripAbove()
int idx;
rememberSelection();
trip = create_and_hookup_trip_from_dive(d);
- for_each_dive(idx, d) {
+ for_each_dive (idx, d) {
if (d->selected)
add_dive_to_trip(d, trip);
}
@@ -610,7 +585,7 @@ void DiveListView::addToTripAbove()
void DiveListView::addToTrip(bool below)
{
- int delta = (currentOrder == Qt::AscendingOrder) ? -1 : +1;
+ int delta = (currentOrder == Qt::AscendingOrder) ? -1 : +1;
struct dive *d = (struct dive *)contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void *>();
rememberSelection();
@@ -623,18 +598,10 @@ void DiveListView::addToTrip(bool below)
if (d->selected) { // we are right-clicking on one of possibly many selected dive(s)
// find the top selected dive, depending on the list order
- if (delta == 1) {
- for_each_dive(idx, d) {
- if (d->selected)
- pd = d;
- }
- d = pd; // this way we have the chronologically last
- } else {
- for_each_dive(idx, d) {
- if (d->selected)
- break; // now that's the chronologically first
- }
- }
+ if (delta == 1)
+ d = last_selected_dive();
+ else
+ d = first_selected_dive();
}
// now find the trip "above" in the dive list
if ((pd = get_dive(get_divenr(d) + delta)) != NULL) {
@@ -645,7 +612,7 @@ void DiveListView::addToTrip(bool below)
return;
add_dive_to_trip(d, trip);
if (d->selected) { // there are possibly other selected dives that we should add
- for_each_dive(idx, d) {
+ for_each_dive (idx, d) {
if (d->selected)
add_dive_to_trip(d, trip);
}
@@ -664,7 +631,7 @@ void DiveListView::markDiveInvalid()
struct dive *d = (struct dive *)contextMenuIndex.data(DiveTripModel::DIVE_ROLE).value<void *>();
if (!d)
return;
- for_each_dive(i, d) {
+ for_each_dive (i, d) {
if (!d->selected)
continue;
//TODO: this should be done in the future
@@ -696,8 +663,7 @@ void DiveListView::deleteDive()
// so instead of using the for_each_dive macro I'm using an explicit for loop
// to make this easier to understand
int lastDiveNr = -1;
- for (i = 0; i < dive_table.nr; i++) {
- d = get_dive(i);
+ for_each_dive (i, d) {
if (!d->selected)
continue;
delete_single_dive(i);
@@ -747,8 +713,23 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event)
if (d) {
popup.addAction(tr("remove dive(s) from trip"), this, SLOT(removeFromTrip()));
popup.addAction(tr("create new trip above"), this, SLOT(newTripAbove()));
- popup.addAction(tr("add dive(s) to trip immediately above"), this, SLOT(addToTripAbove()));
- popup.addAction(tr("add dive(s) to trip immediately below"), this, SLOT(addToTripBelow()));
+ if (!d->divetrip) {
+ struct dive *top = d;
+ struct dive *bottom = d;
+ if (d->selected) {
+ if (currentOrder == Qt::AscendingOrder) {
+ top = first_selected_dive();
+ bottom = last_selected_dive();
+ } else {
+ top = last_selected_dive();
+ bottom = first_selected_dive();
+ }
+ }
+ if (is_trip_before_after(top, (currentOrder == Qt::AscendingOrder)))
+ popup.addAction(tr("add dive(s) to trip immediately above"), this, SLOT(addToTripAbove()));
+ if (is_trip_before_after(bottom, (currentOrder == Qt::DescendingOrder)))
+ popup.addAction(tr("add dive(s) to trip immediately below"), this, SLOT(addToTripBelow()));
+ }
}
if (trip) {
popup.addAction(tr("merge trip with trip above"), this, SLOT(mergeTripAbove()));
@@ -764,14 +745,10 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event)
if (amount_selected > 1 && consecutive_selected())
popup.addAction(tr("merge selected dives"), this, SLOT(mergeDives()));
if (amount_selected >= 1) {
- popup.addAction(tr("save As"), this, SLOT(saveSelectedDivesAs()));
- popup.addAction(tr("export As UDDF"), this, SLOT(exportSelectedDivesAsUDDF()));
- popup.addAction(tr("export As CSV"), this, SLOT(exportSelectedDivesAsCSV()));
+ popup.addAction(tr("renumber dive(s)"), this, SLOT(renumberDives()));
popup.addAction(tr("shift times"), this, SLOT(shiftTimes()));
popup.addAction(tr("load images"), this, SLOT(loadImages()));
}
- if (d)
- popup.addAction(tr("upload dive(s) to divelogs.de"), this, SLOT(uploadToDivelogsDE()));
// "collapse all" really closes all trips,
// "collapse" keeps the trip with the selected dive open
QAction *actionTaken = popup.exec(event->globalPos());
@@ -784,56 +761,6 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event)
event->accept();
}
-void DiveListView::saveSelectedDivesAs()
-{
- QSettings settings;
- QString lastDir = QDir::homePath();
-
- settings.beginGroup("FileDialog");
- if (settings.contains("LastDir")) {
- if (QDir::setCurrent(settings.value("LastDir").toString())) {
- lastDir = settings.value("LastDir").toString();
- }
- }
- settings.endGroup();
-
- QString fileName = QFileDialog::getSaveFileName(MainWindow::instance(), tr("Save Dives As..."), QDir::homePath());
- if (fileName.isEmpty())
- return;
-
- // Keep last open dir
- QFileInfo fileInfo(fileName);
- settings.beginGroup("FileDialog");
- settings.setValue("LastDir", fileInfo.dir().path());
- settings.endGroup();
-
- QByteArray bt = QFile::encodeName(fileName);
- save_dives_logic(bt.data(), true);
-}
-
-void DiveListView::exportSelectedDivesAsUDDF()
-{
- QString filename;
- QFileInfo fi(system_default_filename());
-
- filename = QFileDialog::getSaveFileName(this, tr("Export UDDF File as"), fi.absolutePath(),
- tr("UDDF files (*.uddf *.UDDF)"));
- if (!filename.isNull() && !filename.isEmpty())
- export_dives_xslt(filename.toUtf8(), true, "uddf-export.xslt");
-}
-
-void DiveListView::exportSelectedDivesAsCSV()
-{
- QString filename;
- QFileInfo fi(system_default_filename());
-
- filename = QFileDialog::getSaveFileName(this, tr("Export CSV File as"), fi.absolutePath(),
- tr("CSV files (*.csv *.CSV)"));
- if (!filename.isNull() && !filename.isEmpty())
- export_dives_xslt(filename.toUtf8(), true, "xml2csv.xslt");
-}
-
-
void DiveListView::shiftTimes()
{
ShiftTimesDialog::instance()->show();
@@ -874,11 +801,10 @@ void DiveListView::loadImages()
imagetime += shiftDialog.amount(); // TODO: this should be cached and passed to the C-function
int j = 0;
struct dive *dive;
- for_each_dive(j, dive) {
+ for_each_dive (j, dive) {
if (!dive->selected)
continue;
- dc = &(dive->dc);
- while (dc) {
+ for_each_dc (dive, dc) {
when = dc->when ? dc->when : dive->when;
duration_s = dc->duration.seconds ? dc->duration.seconds : dive->duration.seconds;
if (when - 3600 < imagetime && when + duration_s + 3600 > imagetime) {
@@ -899,17 +825,11 @@ void DiveListView::loadImages()
MainWindow::instance()->refreshDisplay();
MainWindow::instance()->graphics()->replot();
}
- dc = dc->next;
}
}
}
}
-void DiveListView::uploadToDivelogsDE()
-{
- DivelogsDeWebServices::instance()->prepareDivesForUpload();
-}
-
QString DiveListView::lastUsedImageDir()
{
QSettings settings;
diff --git a/qt-ui/divelistview.h b/qt-ui/divelistview.h
index d946b1854..23ca1cc42 100644
--- a/qt-ui/divelistview.h
+++ b/qt-ui/divelistview.h
@@ -48,12 +48,9 @@ slots:
void addToTripAbove();
void addToTripBelow();
void mergeDives();
- void saveSelectedDivesAs();
- void exportSelectedDivesAsUDDF();
- void exportSelectedDivesAsCSV();
+ void renumberDives();
void shiftTimes();
void loadImages();
- void uploadToDivelogsDE();
static QString lastUsedImageDir();
signals:
@@ -67,6 +64,7 @@ private:
DiveTripModel::Layout currentLayout;
QLineEdit searchBox;
QModelIndex contextMenuIndex;
+ bool dontEmitDiveChangedSignal;
/* if dive_trip_t is null, there's no problem. */
QMultiHash<dive_trip_t *, int> selectedDives;
diff --git a/qt-ui/divelogexportdialog.cpp b/qt-ui/divelogexportdialog.cpp
new file mode 100644
index 000000000..28f343257
--- /dev/null
+++ b/qt-ui/divelogexportdialog.cpp
@@ -0,0 +1,98 @@
+#include <QFileDialog>
+#include <QString>
+#include <QShortcut>
+#include <QAbstractButton>
+#include <QDebug>
+#include <QSettings>
+
+#include "mainwindow.h"
+#include "divelogexportdialog.h"
+#include "ui_divelogexportdialog.h"
+#include "subsurfacewebservices.h"
+#include "worldmap-save.h"
+
+DiveLogExportDialog::DiveLogExportDialog(QWidget *parent) : QDialog(parent),
+ ui(new Ui::DiveLogExportDialog)
+{
+ ui->setupUi(this);
+ showExplanation();
+ QShortcut *quit = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this);
+ connect(quit, SIGNAL(activated()), parent, SLOT(close()));
+ QShortcut *close = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this);
+ connect(close, SIGNAL(activated()), this, SLOT(close()));
+}
+
+DiveLogExportDialog::~DiveLogExportDialog()
+{
+ delete ui;
+}
+
+void DiveLogExportDialog::showExplanation()
+{
+ if (ui->exportUDDF->isChecked()) {
+ ui->description->setText("Generic format that is used for data exchange between a variety of diving related programs.");
+ } else if (ui->exportCSV->isChecked()) {
+ ui->description->setText("Comma separated values that include the most relevant information of the dive profile.");
+ } else if (ui->exportDivelogs->isChecked()) {
+ ui->description->setText("Send the dive data to Divelogs.de website.");
+ } else if (ui->exportWorldMap->isChecked()) {
+ ui->description->setText("HTML export of the dive locations, visualized on a world map.");
+ } else if (ui->exportSubsurfaceXML->isChecked()) {
+ ui->description->setText("Subsurface native XML format.");
+ }
+}
+
+void DiveLogExportDialog::on_exportGroup_buttonClicked(QAbstractButton *button)
+{
+ showExplanation();
+}
+
+void DiveLogExportDialog::on_buttonBox_accepted()
+{
+ QString filename;
+ QString stylesheet;
+ QSettings settings;
+ QString lastDir = QDir::homePath();
+
+ settings.beginGroup("FileDialog");
+ if (settings.contains("LastDir")) {
+ if (QDir::setCurrent(settings.value("LastDir").toString())) {
+ lastDir = settings.value("LastDir").toString();
+ }
+ }
+ settings.endGroup();
+
+ if (ui->exportUDDF->isChecked()) {
+ stylesheet = "uddf-export.xslt";
+ filename = QFileDialog::getSaveFileName(this, tr("Export UDDF File as"), lastDir,
+ tr("UDDF files (*.uddf *.UDDF)"));
+ } else if (ui->exportCSV->isChecked()) {
+ stylesheet = "xml2csv.xslt";
+ filename = QFileDialog::getSaveFileName(this, tr("Export CSV File as"), lastDir,
+ tr("CSV files (*.csv *.CSV)"));
+ } else if (ui->exportDivelogs->isChecked()) {
+ DivelogsDeWebServices::instance()->prepareDivesForUpload(ui->exportSelected->isChecked());
+ } else if (ui->exportWorldMap->isChecked()) {
+ filename = QFileDialog::getSaveFileName(this, tr("Export World Map"), lastDir,
+ tr("HTML files (*.html)"));
+ if (!filename.isNull() && !filename.isEmpty())
+ export_worldmap_HTML(filename.toUtf8().data(), ui->exportSelected->isChecked());
+ } else if (ui->exportSubsurfaceXML->isChecked()) {
+ filename = QFileDialog::getSaveFileName(this, tr("Export Subsurface XML"), lastDir,
+ tr("XML files (*.xml *.ssrf)"));
+ if (!filename.isNull() && !filename.isEmpty()) {
+ QByteArray bt = QFile::encodeName(filename);
+ save_dives_logic(bt.data(), true);
+ }
+ }
+ if (!filename.isNull() && !filename.isEmpty()) {
+ // remember the last export path
+ QFileInfo fileInfo(filename);
+ settings.beginGroup("FileDialog");
+ settings.setValue("LastDir", fileInfo.dir().path());
+ settings.endGroup();
+ // the non XSLT exports are called directly above, the XSLT based ons are called here
+ if (!stylesheet.isEmpty())
+ export_dives_xslt(filename.toUtf8(), ui->exportSelected->isChecked(), stylesheet.toStdString().c_str());
+ }
+}
diff --git a/qt-ui/divelogexportdialog.h b/qt-ui/divelogexportdialog.h
new file mode 100644
index 000000000..92510a7aa
--- /dev/null
+++ b/qt-ui/divelogexportdialog.h
@@ -0,0 +1,28 @@
+#ifndef DIVELOGEXPORTDIALOG_H
+#define DIVELOGEXPORTDIALOG_H
+
+#include <QDialog>
+#include <QAbstractButton>
+
+namespace Ui {
+ class DiveLogExportDialog;
+}
+
+class DiveLogExportDialog : public QDialog {
+ Q_OBJECT
+
+public:
+ explicit DiveLogExportDialog(QWidget *parent = 0);
+ ~DiveLogExportDialog();
+
+private
+slots:
+ void on_buttonBox_accepted();
+ void on_exportGroup_buttonClicked(QAbstractButton *);
+
+private:
+ Ui::DiveLogExportDialog *ui;
+ void showExplanation();
+};
+
+#endif // DIVELOGEXPORTDIALOG_H
diff --git a/qt-ui/divelogexportdialog.ui b/qt-ui/divelogexportdialog.ui
new file mode 100644
index 000000000..72e373127
--- /dev/null
+++ b/qt-ui/divelogexportdialog.ui
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DiveLogExportDialog</class>
+ <widget class="QDialog" name="DiveLogExportDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>448</width>
+ <height>473</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Export Dive Log Files</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>420</y>
+ <width>341</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label_3">
+ <property name="geometry">
+ <rect>
+ <x>-50</x>
+ <y>10</y>
+ <width>497</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="font">
+ <font>
+ <family>Droid Sans [unknown]</family>
+ <pointsize>14</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="text">
+ <string>Export Dive Log Files</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QGroupBox" name="exportFormat">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>70</y>
+ <width>201</width>
+ <height>211</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Export format</string>
+ </property>
+ <widget class="QRadioButton" name="exportUDDF">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>70</y>
+ <width>110</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>110</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>UDDF</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">exportGroup</string>
+ </attribute>
+ </widget>
+ <widget class="QRadioButton" name="exportDivelogs">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>100</y>
+ <width>131</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>divelogs.de</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">exportGroup</string>
+ </attribute>
+ </widget>
+ <widget class="QRadioButton" name="exportCSV">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>130</y>
+ <width>110</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>CSV</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">exportGroup</string>
+ </attribute>
+ </widget>
+ <widget class="QRadioButton" name="exportWorldMap">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>160</y>
+ <width>171</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Worldmap</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">exportGroup</string>
+ </attribute>
+ </widget>
+ <widget class="QRadioButton" name="exportSubsurfaceXML">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>40</y>
+ <width>171</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>171</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Subsurface XML</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">exportGroup</string>
+ </attribute>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" name="exportSelection">
+ <property name="geometry">
+ <rect>
+ <x>240</x>
+ <y>70</y>
+ <width>191</width>
+ <height>141</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Selection</string>
+ </property>
+ <widget class="QRadioButton" name="exportSelected">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>151</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Selected dives</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="exportAll">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>60</y>
+ <width>110</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>All dives</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="Line" name="line">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>280</y>
+ <width>231</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" name="description">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>310</y>
+ <width>341</width>
+ <height>91</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>DiveLogExportDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>DiveLogExportDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <buttongroups>
+ <buttongroup name="exportGroup"/>
+ </buttongroups>
+</ui>
diff --git a/qt-ui/divelogimportdialog.h b/qt-ui/divelogimportdialog.h
index 4c499b03e..fb44faa94 100644
--- a/qt-ui/divelogimportdialog.h
+++ b/qt-ui/divelogimportdialog.h
@@ -6,8 +6,7 @@
#include "../dive.h"
#include "../divelist.h"
-namespace Ui
-{
+namespace Ui {
class DiveLogImportDialog;
}
diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp
index 24aa7f697..ada2b4e73 100644
--- a/qt-ui/diveplanner.cpp
+++ b/qt-ui/diveplanner.cpp
@@ -43,264 +43,6 @@ QString dpGasToStr(const divedatapoint &p)
static DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
-DivePlannerGraphics::DivePlannerGraphics(QWidget *parent) : QGraphicsView(parent),
- verticalLine(new QGraphicsLineItem(fromPercent(0, Qt::Horizontal), fromPercent(0, Qt::Vertical), fromPercent(0, Qt::Horizontal), fromPercent(100, Qt::Vertical))),
- horizontalLine(new QGraphicsLineItem(fromPercent(0, Qt::Horizontal), fromPercent(0, Qt::Vertical), fromPercent(100, Qt::Horizontal), fromPercent(0, Qt::Vertical))),
- activeDraggedHandler(0),
- diveBg(new QGraphicsPolygonItem()),
- timeLine(new Ruler()),
- timeString(new QGraphicsSimpleTextItem()),
- depthString(new QGraphicsSimpleTextItem()),
- depthHandler(new ExpanderGraphics()),
- timeHandler(new ExpanderGraphics()),
- minMinutes(TIME_INITIAL_MAX),
- minDepth(M_OR_FT(40, 120)),
- dpMaxTime(0)
-{
- setBackgroundBrush(profile_color[BACKGROUND].at(0));
- setMouseTracking(true);
- setScene(new QGraphicsScene());
- scene()->setSceneRect(0, 0, 1920, 1080);
-
- verticalLine->setPen(QPen(Qt::DotLine));
- scene()->addItem(verticalLine);
-
- horizontalLine->setPen(QPen(Qt::DotLine));
- scene()->addItem(horizontalLine);
-
- timeLine->setMinimum(0);
- timeLine->setMaximum(TIME_INITIAL_MAX);
- timeLine->setTickInterval(10);
- timeLine->setColor(getColor(TIME_GRID));
- timeLine->setLine(fromPercent(10, Qt::Horizontal),
- fromPercent(85, Qt::Vertical),
- fromPercent(90, Qt::Horizontal),
- fromPercent(85, Qt::Vertical));
- timeLine->setOrientation(Qt::Horizontal);
- timeLine->setTickSize(fromPercent(1, Qt::Vertical));
- timeLine->setTextColor(getColor(TIME_TEXT));
- timeLine->updateTicks();
- scene()->addItem(timeLine);
-
- depthLine = new Ruler();
- depthLine->setMinimum(0);
- depthLine->setMaximum(M_OR_FT(40, 120));
- depthLine->setTickInterval(M_OR_FT(10, 30));
- depthLine->setLine(fromPercent(10, Qt::Horizontal),
- fromPercent(10, Qt::Vertical),
- fromPercent(10, Qt::Horizontal),
- fromPercent(85, Qt::Vertical));
- depthLine->setOrientation(Qt::Vertical);
- depthLine->setTickSize(fromPercent(1, Qt::Horizontal));
- depthLine->setColor(getColor(DEPTH_GRID));
- depthLine->setTextColor(getColor(SAMPLE_DEEP));
- depthLine->updateTicks();
- depthLine->unitSystem = prefs.units.length;
- scene()->addItem(depthLine);
-
- timeString->setFlag(QGraphicsItem::ItemIgnoresTransformations);
- timeString->setBrush(profile_color[TIME_TEXT].at(0));
- scene()->addItem(timeString);
-
- depthString->setFlag(QGraphicsItem::ItemIgnoresTransformations);
- depthString->setBrush(profile_color[SAMPLE_DEEP].at(0));
- scene()->addItem(depthString);
-
- diveBg->setPen(QPen(QBrush(), 0));
- scene()->addItem(diveBg);
-
- QString incrText;
- if (prefs.units.length == units::METERS)
- incrText = tr("10m");
- else
- incrText = tr("30ft");
-
- timeHandler->increaseBtn->setPixmap(QString(":plan_plus"));
- timeHandler->decreaseBtn->setPixmap(QString(":plan_minus"));
- timeHandler->icon->setPixmap(QString(":icon_time"));
- connect(timeHandler->increaseBtn, SIGNAL(clicked()), this, SLOT(increaseTime()));
- connect(timeHandler->decreaseBtn, SIGNAL(clicked()), this, SLOT(decreaseTime()));
- timeHandler->setPos(fromPercent(83, Qt::Horizontal), fromPercent(100, Qt::Vertical));
- timeHandler->setZValue(-2);
- scene()->addItem(timeHandler);
-
- depthHandler->increaseBtn->setPixmap(QString(":arrow_down"));
- depthHandler->decreaseBtn->setPixmap(QString(":arrow_up"));
- depthHandler->icon->setPixmap(QString(":icon_depth"));
- connect(depthHandler->decreaseBtn, SIGNAL(clicked()), this, SLOT(decreaseDepth()));
- connect(depthHandler->increaseBtn, SIGNAL(clicked()), this, SLOT(increaseDepth()));
- depthHandler->setPos(fromPercent(0, Qt::Horizontal), fromPercent(100, Qt::Vertical));
- depthHandler->setZValue(-2);
- scene()->addItem(depthHandler);
-
- QAction *action = NULL;
-
-#define ADD_ACTION(SHORTCUT, Slot) \
- action = new QAction(this); \
- action->setShortcut(SHORTCUT); \
- action->setShortcutContext(Qt::WindowShortcut); \
- addAction(action); \
- connect(action, SIGNAL(triggered(bool)), this, SLOT(Slot))
-
- ADD_ACTION(Qt::Key_Escape, keyEscAction());
- ADD_ACTION(Qt::Key_Delete, keyDeleteAction());
- ADD_ACTION(Qt::Key_Up, keyUpAction());
- ADD_ACTION(Qt::Key_Down, keyDownAction());
- ADD_ACTION(Qt::Key_Left, keyLeftAction());
- ADD_ACTION(Qt::Key_Right, keyRightAction());
-#undef ADD_ACTION
-
- connect(plannerModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(drawProfile()));
- connect(plannerModel, SIGNAL(cylinderModelEdited()), this, SLOT(drawProfile()));
-
- connect(plannerModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
- this, SLOT(pointInserted(const QModelIndex &, int, int)));
- connect(plannerModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
- this, SLOT(pointsRemoved(const QModelIndex &, int, int)));
- setRenderHint(QPainter::Antialiasing);
-}
-
-void DivePlannerGraphics::settingsChanged()
-{
- if (depthLine->unitSystem == prefs.units.length)
- return;
-
- depthLine->setTickInterval(M_OR_FT(10, 30));
- depthLine->updateTicks();
- depthLine->unitSystem = prefs.units.length;
-}
-
-void DivePlannerGraphics::pointInserted(const QModelIndex &parent, int start, int end)
-{
- DiveHandler *item = new DiveHandler();
- scene()->addItem(item);
- handles << item;
-
- QGraphicsSimpleTextItem *gasChooseBtn = new QGraphicsSimpleTextItem();
- scene()->addItem(gasChooseBtn);
- gasChooseBtn->setZValue(10);
- gasChooseBtn->setFlag(QGraphicsItem::ItemIgnoresTransformations);
- gases << gasChooseBtn;
- if (plannerModel->recalcQ())
- drawProfile();
-}
-
-void DivePlannerGraphics::keyDownAction()
-{
- Q_FOREACH(QGraphicsItem * i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- int row = handles.indexOf(handler);
- divedatapoint dp = plannerModel->at(row);
- if (dp.depth >= depthLine->maximum())
- continue;
-
- dp.depth += M_OR_FT(1, 5);
- plannerModel->editStop(row, dp);
- }
- }
-}
-
-void DivePlannerGraphics::keyUpAction()
-{
- Q_FOREACH(QGraphicsItem * i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- int row = handles.indexOf(handler);
- divedatapoint dp = plannerModel->at(row);
-
- if (dp.depth <= 0)
- continue;
-
- dp.depth -= M_OR_FT(1, 5);
- plannerModel->editStop(row, dp);
- }
- }
- drawProfile();
-}
-
-void DivePlannerGraphics::keyLeftAction()
-{
- Q_FOREACH(QGraphicsItem * i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- int row = handles.indexOf(handler);
- divedatapoint dp = plannerModel->at(row);
-
- if (dp.time / 60 <= 0)
- continue;
-
- // don't overlap positions.
- // maybe this is a good place for a 'goto'?
- double xpos = timeLine->posAtValue((dp.time - 60) / 60);
- bool nextStep = false;
- Q_FOREACH(DiveHandler * h, handles) {
- if (IS_FP_SAME(h->pos().x(), xpos)) {
- nextStep = true;
- break;
- }
- }
- if (nextStep)
- continue;
-
- dp.time -= 60;
- plannerModel->editStop(row, dp);
- }
- }
-}
-
-void DivePlannerGraphics::keyRightAction()
-{
- Q_FOREACH(QGraphicsItem * i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- int row = handles.indexOf(handler);
- divedatapoint dp = plannerModel->at(row);
- if (dp.time / 60 >= timeLine->maximum())
- continue;
-
- // don't overlap positions.
- // maybe this is a good place for a 'goto'?
- double xpos = timeLine->posAtValue((dp.time + 60) / 60);
- bool nextStep = false;
- Q_FOREACH(DiveHandler * h, handles) {
- if (IS_FP_SAME(h->pos().x(), xpos)) {
- nextStep = true;
- break;
- }
- }
- if (nextStep)
- continue;
-
- dp.time += 60;
- plannerModel->editStop(row, dp);
- }
- }
-}
-
-void DivePlannerGraphics::keyDeleteAction()
-{
- int selCount = scene()->selectedItems().count();
- if (selCount) {
- QVector<int> selectedIndexes;
- Q_FOREACH(QGraphicsItem * i, scene()->selectedItems()) {
- if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
- selectedIndexes.push_back(handles.indexOf(handler));
- }
- }
- plannerModel->removeSelectedPoints(selectedIndexes);
- }
-}
-
-void DivePlannerGraphics::pointsRemoved(const QModelIndex &, int start, int end)
-{ // start and end are inclusive.
- int num = (end - start) + 1;
- for (int i = num; i != 0; i--) {
- delete handles.back();
- handles.pop_back();
- delete gases.back();
- gases.pop_back();
- }
- scene()->clearSelection();
- drawProfile();
-}
-
bool intLessThan(int a, int b)
{
return a <= b;
@@ -317,83 +59,6 @@ void DivePlannerPointsModel::removeSelectedPoints(const QVector<int> &rows)
endRemoveRows();
}
-void DivePlannerGraphics::keyEscAction()
-{
- if (scene()->selectedItems().count()) {
- scene()->clearSelection();
- return;
- }
- if (DivePlannerPointsModel::instance()->isPlanner())
- plannerModel->cancelPlan();
-}
-
-qreal DivePlannerGraphics::fromPercent(qreal percent, Qt::Orientation orientation)
-{
- qreal total = orientation == Qt::Horizontal ? sceneRect().width() : sceneRect().height();
- qreal result = (total * percent) / 100;
- return result;
-}
-
-void DivePlannerGraphics::increaseDepth()
-{
- if (depthLine->maximum() + M_OR_FT(10, 30) > MAX_DEPTH)
- return;
- minDepth += M_OR_FT(10, 30);
- depthLine->setMaximum(minDepth);
- depthLine->updateTicks();
- drawProfile();
-}
-
-void DivePlannerGraphics::increaseTime()
-{
- minMinutes += 10;
- timeLine->setMaximum(minMinutes);
- timeLine->updateTicks();
- drawProfile();
-}
-
-void DivePlannerGraphics::decreaseDepth()
-{
- if (depthLine->maximum() - M_OR_FT(10, 30) < MIN_DEPTH)
- return;
-
- Q_FOREACH(DiveHandler * d, handles) {
- if (depthLine->valueAt(d->pos()) > depthLine->maximum() - M_OR_FT(10, 30)) {
- QMessageBox::warning(MainWindow::instance(),
- tr("Handler Position Error"),
- tr("One or more of your stops will be lost with this operations, \n"
- "Please, remove them first."));
- return;
- }
- }
- minDepth -= M_OR_FT(10, 30);
- depthLine->setMaximum(minDepth);
- depthLine->updateTicks();
- drawProfile();
-}
-
-void DivePlannerGraphics::decreaseTime()
-{
- if (timeLine->maximum() - 10 < TIME_INITIAL_MAX || timeLine->maximum() - 10 < dpMaxTime)
- return;
-
- minMinutes -= 10;
- timeLine->setMaximum(timeLine->maximum() - 10);
- timeLine->updateTicks();
- drawProfile();
-}
-
-void DivePlannerGraphics::mouseDoubleClickEvent(QMouseEvent *event)
-{
- QPointF mappedPos = mapToScene(event->pos());
- if (isPointOutOfBoundaries(mappedPos))
- return;
-
- int minutes = rint(timeLine->valueAt(mappedPos));
- int milimeters = rint(depthLine->valueAt(mappedPos) / M_OR_FT(1, 1)) * M_OR_FT(1, 1);
- plannerModel->addStop(milimeters, minutes * 60, -1, 0, 0, true);
-}
-
void DivePlannerPointsModel::createSimpleDive()
{
// plannerModel->addStop(0, 0, O2_IN_AIR, 0, 0);
@@ -470,252 +135,31 @@ void DivePlannerPointsModel::removeDeco()
setRecalc(oldrec);
}
+#if 0
void DivePlannerGraphics::drawProfile()
{
- if (!plannerModel->recalcQ())
- return;
- qDeleteAll(lines);
- lines.clear();
-
- plannerModel->createTemporaryPlan();
- struct diveplan diveplan = plannerModel->getDiveplan();
- struct divedatapoint *dp = diveplan.dp;
- unsigned int max_depth = 0;
-
- if (!dp) {
- plannerModel->deleteTemporaryPlan();
- return;
- }
- //TODO: divedatapoint_list_get_max_depth on C - code?
- while (dp->next) {
- if (dp->time && dp->depth > max_depth)
- max_depth = dp->depth;
- dp = dp->next;
- }
-
- if (!activeDraggedHandler && (timeLine->maximum() < dp->time / 60.0 + 5 || dp->time / 60.0 + 15 < timeLine->maximum())) {
- minMinutes = fmax(dp->time / 60.0 + 5, minMinutes);
- timeLine->setMaximum(minMinutes);
- timeLine->updateTicks();
- }
- if (!activeDraggedHandler && (depthLine->maximum() < max_depth + M_OR_FT(10, 30) || max_depth + M_OR_FT(10, 30) < depthLine->maximum())) {
- minDepth = fmax(max_depth + M_OR_FT(10, 30), minDepth);
- depthLine->setMaximum(minDepth);
- depthLine->updateTicks();
- }
-
- // Re-position the user generated dive handlers
- int last = 0;
- for (int i = 0; i < plannerModel->rowCount(); i++) {
- struct divedatapoint datapoint = plannerModel->at(i);
- if (datapoint.time == 0) // those are the magic entries for tanks
- continue;
- DiveHandler *h = handles.at(i);
- h->setPos(timeLine->posAtValue(datapoint.time / 60), depthLine->posAtValue(datapoint.depth));
- QPointF p1 = (last == i) ? QPointF(timeLine->posAtValue(0), depthLine->posAtValue(0)) : handles[last]->pos();
- QPointF p2 = handles[i]->pos();
- QLineF line(p1, p2);
- QPointF pos = line.pointAt(0.5);
- gases[i]->setPos(pos);
- gases[i]->setText(dpGasToStr(plannerModel->at(i)));
- last = i;
- }
-
- // (re-) create the profile with different colors for segments that were
- // entered vs. segments that were calculated
- double lastx = timeLine->posAtValue(0);
- double lasty = depthLine->posAtValue(0);
-
- QPolygonF poly;
- poly.append(QPointF(lastx, lasty));
-
+ // Code ported to the new profile is deleted. This part that I left here
+ // is because I didn't fully understood the reason of the magic with
+ // the plannerModel.
bool oldRecalc = plannerModel->setRecalc(false);
plannerModel->removeDeco();
-
- unsigned int lastdepth = 0;
- for (dp = diveplan.dp; dp != NULL; dp = dp->next) {
- if (dp->time == 0) // magic entry for available tank
- continue;
- double xpos = timeLine->posAtValue(dp->time / 60.0);
- double ypos = depthLine->posAtValue(dp->depth);
- if (!dp->entered) {
- QGraphicsLineItem *item = new QGraphicsLineItem(lastx, lasty, xpos, ypos);
- item->setPen(QPen(QBrush(Qt::red), 0));
-
- scene()->addItem(item);
- lines << item;
- if (dp->depth) {
- if (dp->depth == lastdepth || dp->o2 != dp->next->o2 || dp->he != dp->next->he)
- plannerModel->addStop(dp->depth, dp->time, dp->next->o2, dp->next->he, 0, false);
- lastdepth = dp->depth;
- }
- }
- lastx = xpos;
- lasty = ypos;
- poly.append(QPointF(lastx, lasty));
- }
+ // Here we plotted the old planner profile. why there's the magic with the plannerModel here?
plannerModel->setRecalc(oldRecalc);
-
- diveBg->setPolygon(poly);
- QRectF b = poly.boundingRect();
- QLinearGradient pat(
- b.x(),
- b.y(),
- b.x(),
- b.height() + b.y());
-
- pat.setColorAt(1, profile_color[DEPTH_BOTTOM].first());
- pat.setColorAt(0, profile_color[DEPTH_TOP].first());
- diveBg->setBrush(pat);
-
plannerModel->deleteTemporaryPlan();
}
-
-void DivePlannerGraphics::resizeEvent(QResizeEvent *event)
-{
- QGraphicsView::resizeEvent(event);
- fitInView(sceneRect(), Qt::IgnoreAspectRatio);
-}
-
-void DivePlannerGraphics::showEvent(QShowEvent *event)
-{
- QGraphicsView::showEvent(event);
- fitInView(sceneRect(), Qt::IgnoreAspectRatio);
-}
-
-void DivePlannerGraphics::mouseMoveEvent(QMouseEvent *event)
-{
- QPointF mappedPos = mapToScene(event->pos());
-
-
- double xpos = timeLine->valueAt(mappedPos);
- double ypos = depthLine->valueAt(mappedPos);
-
- xpos = (xpos > timeLine->maximum()) ? timeLine->posAtValue(timeLine->maximum()) : (xpos < timeLine->minimum()) ? timeLine->posAtValue(timeLine->minimum()) : timeLine->posAtValue(xpos);
-
- ypos = (ypos > depthLine->maximum()) ? depthLine->posAtValue(depthLine->maximum()) : (ypos < depthLine->minimum()) ? depthLine->posAtValue(depthLine->minimum()) : depthLine->posAtValue(ypos);
-
- verticalLine->setPos(xpos, fromPercent(0, Qt::Vertical));
- horizontalLine->setPos(fromPercent(0, Qt::Horizontal), ypos);
-
- depthString->setPos(fromPercent(1, Qt::Horizontal), ypos);
- timeString->setPos(xpos + 1, fromPercent(95, Qt::Vertical));
-
- if (isPointOutOfBoundaries(mappedPos))
- return;
-
- depthString->setText(get_depth_string(depthLine->valueAt(mappedPos), true, false));
- timeString->setText(QString::number(rint(timeLine->valueAt(mappedPos))) + "min");
-
- // calculate the correct color for the depthString.
- // QGradient doesn't returns it's interpolation, meh.
- double percent = depthLine->percentAt(mappedPos);
- QColor &startColor = profile_color[SAMPLE_SHALLOW].first();
- QColor &endColor = profile_color[SAMPLE_DEEP].first();
- short redDelta = (endColor.red() - startColor.red()) * percent + startColor.red();
- short greenDelta = (endColor.green() - startColor.green()) * percent + startColor.green();
- short blueDelta = (endColor.blue() - startColor.blue()) * percent + startColor.blue();
- depthString->setBrush(QColor(redDelta, greenDelta, blueDelta));
-
- if (activeDraggedHandler)
- moveActiveHandler(mappedPos, handles.indexOf(activeDraggedHandler));
- if (!handles.count())
- return;
-
- if (handles.last()->x() > mappedPos.x()) {
- verticalLine->setPen(QPen(QBrush(Qt::red), 0, Qt::SolidLine));
- horizontalLine->setPen(QPen(QBrush(Qt::red), 0, Qt::SolidLine));
- } else {
- verticalLine->setPen(QPen(Qt::DotLine));
- horizontalLine->setPen(QPen(Qt::DotLine));
- }
-}
-
-void DivePlannerGraphics::moveActiveHandler(const QPointF &mappedPos, const int pos)
-{
- divedatapoint data = plannerModel->at(pos);
- int mintime = 0, maxtime = (timeLine->maximum() + 10) * 60;
- if (pos > 0)
- mintime = plannerModel->at(pos - 1).time;
- if (pos < plannerModel->size() - 1)
- maxtime = plannerModel->at(pos + 1).time;
-
- int minutes = rint(timeLine->valueAt(mappedPos));
- if (minutes * 60 <= mintime || minutes * 60 >= maxtime)
- return;
-
- int milimeters = rint(depthLine->valueAt(mappedPos) / M_OR_FT(1, 1)) * M_OR_FT(1, 1);
- double xpos = timeLine->posAtValue(minutes);
- double ypos = depthLine->posAtValue(milimeters);
-
- data.depth = milimeters;
- data.time = rint(timeLine->valueAt(mappedPos)) * 60;
-
- plannerModel->editStop(pos, data);
-
- activeDraggedHandler->setPos(QPointF(xpos, ypos));
- qDeleteAll(lines);
- lines.clear();
- drawProfile();
-}
-
-bool DivePlannerGraphics::isPointOutOfBoundaries(const QPointF &point)
-{
- double xpos = timeLine->valueAt(point);
- double ypos = depthLine->valueAt(point);
-
- if (xpos > timeLine->maximum() ||
- xpos < timeLine->minimum() ||
- ypos > depthLine->maximum() ||
- ypos < depthLine->minimum()) {
- return true;
- }
- return false;
-}
-
-void DivePlannerGraphics::mousePressEvent(QMouseEvent *event)
-{
- if (event->modifiers()) {
- QGraphicsView::mousePressEvent(event);
- return;
- }
-
- QPointF mappedPos = mapToScene(event->pos());
- if (event->button() == Qt::LeftButton) {
- Q_FOREACH(QGraphicsItem * item, scene()->items(mappedPos, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder, transform())) {
- if (DiveHandler *h = qgraphicsitem_cast<DiveHandler *>(item)) {
- activeDraggedHandler = h;
- activeDraggedHandler->setBrush(Qt::red);
- originalHandlerPos = activeDraggedHandler->pos();
- }
- }
- }
- QGraphicsView::mousePressEvent(event);
-}
-
-void DivePlannerGraphics::mouseReleaseEvent(QMouseEvent *event)
-{
- if (activeDraggedHandler) {
- /* we already deal with all the positioning in the life update,
- * so all we need to do here is change the color of the handler */
- activeDraggedHandler->setBrush(QBrush(Qt::white));
- activeDraggedHandler = 0;
- drawProfile();
- }
-}
+#endif
DiveHandler::DiveHandler() : QGraphicsEllipseItem()
{
setRect(-5, -5, 10, 10);
- setFlag(QGraphicsItem::ItemIgnoresTransformations);
- setFlag(QGraphicsItem::ItemIsSelectable);
+ setFlags(ItemIgnoresTransformations | ItemIsSelectable | ItemIsMovable | ItemSendsGeometryChanges);
setBrush(Qt::white);
setZValue(2);
}
int DiveHandler::parentIndex()
{
- DivePlannerGraphics *view = qobject_cast<DivePlannerGraphics *>(scene()->views().first());
+ ProfileWidget2 *view = qobject_cast<ProfileWidget2 *>(scene()->views().first());
return view->handles.indexOf(this);
}
@@ -739,7 +183,7 @@ void DiveHandler::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
void DiveHandler::selfRemove()
{
setSelected(true);
- DivePlannerGraphics *view = qobject_cast<DivePlannerGraphics *>(scene()->views().first());
+ ProfileWidget2 *view = qobject_cast<ProfileWidget2 *>(scene()->views().first());
view->keyDeleteAction();
}
@@ -750,210 +194,13 @@ void DiveHandler::changeGas()
plannerModel->setData(index, action->text());
}
-void DiveHandler::mousePressEvent(QGraphicsSceneMouseEvent *event)
+void DiveHandler::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
- if (event->button() != Qt::LeftButton)
+ ProfileWidget2 *view = qobject_cast<ProfileWidget2*>(scene()->views().first());
+ if(view->isPointOutOfBoundaries(event->scenePos()))
return;
-
- if (event->modifiers().testFlag(Qt::ControlModifier)) {
- setSelected(true);
- }
- // mousePressEvent 'grabs' the mouse and keyboard, annoying.
- ungrabMouse();
-
- /* hack. Sometimes the keyboard is grabbed, sometime it's not,
- so, let's force a grab and release, to get rid of a warning. */
- grabKeyboard();
- ungrabKeyboard();
-}
-
-void Ruler::setMaximum(double maximum)
-{
- max = maximum;
-}
-
-void Ruler::setMinimum(double minimum)
-{
- min = minimum;
-}
-
-void Ruler::setTextColor(const QColor &color)
-{
- textColor = color;
-}
-
-void Ruler::eraseAll()
-{
- qDeleteAll(ticks);
- ticks.clear();
- qDeleteAll(labels);
- labels.clear();
-}
-
-Ruler::Ruler() : unitSystem(0),
- orientation(Qt::Horizontal),
- min(0),
- max(0),
- interval(0),
- tickSize(0)
-{
-}
-
-Ruler::~Ruler()
-{
- eraseAll();
-}
-
-void Ruler::setOrientation(Qt::Orientation o)
-{
- orientation = o;
- // position the elements on the screen.
- setMinimum(minimum());
- setMaximum(maximum());
-}
-
-void Ruler::updateTicks()
-{
- eraseAll();
-
- QLineF m = line();
- QGraphicsLineItem *item = NULL;
- QGraphicsSimpleTextItem *label = NULL;
-
- double steps = (max - min) / interval;
- qreal pos;
- double currValue = min;
-
- if (orientation == Qt::Horizontal) {
- double stepSize = (m.x2() - m.x1()) / steps;
- for (pos = m.x1(); pos <= m.x2(); pos += stepSize, currValue += interval) {
- item = new QGraphicsLineItem(pos, m.y1(), pos, m.y1() + tickSize, this);
- item->setPen(pen());
- ticks.push_back(item);
-
- label = new QGraphicsSimpleTextItem(QString::number(currValue), this);
- label->setBrush(QBrush(textColor));
- label->setFlag(ItemIgnoresTransformations);
- label->setPos(pos - label->boundingRect().width() / 2, m.y1() + tickSize + 5);
- labels.push_back(label);
- }
- } else {
- double stepSize = (m.y2() - m.y1()) / steps;
- for (pos = m.y1(); pos <= m.y2(); pos += stepSize, currValue += interval) {
- item = new QGraphicsLineItem(m.x1(), pos, m.x1() - tickSize, pos, this);
- item->setPen(pen());
- ticks.push_back(item);
-
- label = new QGraphicsSimpleTextItem(get_depth_string(currValue, false, false), this);
- label->setBrush(QBrush(textColor));
- label->setFlag(ItemIgnoresTransformations);
- label->setPos(m.x2() - 80, pos);
- labels.push_back(label);
- }
- }
-}
-
-void Ruler::setTickSize(qreal size)
-{
- tickSize = size;
-}
-
-void Ruler::setTickInterval(double i)
-{
- interval = i;
-}
-
-qreal Ruler::valueAt(const QPointF &p)
-{
- QLineF m = line();
- double retValue = orientation == Qt::Horizontal ?
- max * (p.x() - m.x1()) / (m.x2() - m.x1()) :
- max * (p.y() - m.y1()) / (m.y2() - m.y1());
- return retValue;
-}
-
-qreal Ruler::posAtValue(qreal value)
-{
- QLineF m = line();
- double size = max - min;
- double percent = value / size;
- double realSize = orientation == Qt::Horizontal ?
- m.x2() - m.x1() :
- m.y2() - m.y1();
- double retValue = realSize * percent;
- retValue = (orientation == Qt::Horizontal) ?
- retValue + m.x1() :
- retValue + m.y1();
- return retValue;
-}
-
-qreal Ruler::percentAt(const QPointF &p)
-{
- qreal value = valueAt(p);
- double size = max - min;
- double percent = value / size;
- return percent;
-}
-
-double Ruler::maximum() const
-{
- return max;
-}
-
-double Ruler::minimum() const
-{
- return min;
-}
-
-void Ruler::setColor(const QColor &color)
-{
- QPen defaultPen(color);
- defaultPen.setJoinStyle(Qt::RoundJoin);
- defaultPen.setCapStyle(Qt::RoundCap);
- defaultPen.setWidth(2);
- defaultPen.setCosmetic(true);
- setPen(defaultPen);
-}
-
-Button::Button(QObject *parent, QGraphicsItem *itemParent) : QObject(parent),
- QGraphicsRectItem(itemParent),
- icon(new QGraphicsPixmapItem(this)),
- text(new QGraphicsSimpleTextItem(this))
-{
- icon->setPos(0, 0);
- text->setPos(0, 0);
- setFlag(ItemIgnoresTransformations);
- setPen(QPen(QBrush(), 0));
-}
-
-void Button::setPixmap(const QPixmap &pixmap)
-{
- icon->setPixmap(pixmap);
- if (pixmap.isNull())
- icon->hide();
- else
- icon->show();
-
- setRect(childrenBoundingRect());
-}
-
-void Button::setText(const QString &t)
-{
- text->setText(t);
- if (icon->pixmap().isNull()) {
- icon->hide();
- text->setPos(0, 0);
- } else {
- icon->show();
- text->setPos(22, 0);
- }
- setRect(childrenBoundingRect());
-}
-
-void Button::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- event->ignore();
- emit clicked();
+ QGraphicsEllipseItem::mouseMoveEvent(event);
+ emit moved();
}
DivePlannerWidget::DivePlannerWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
@@ -982,11 +229,11 @@ DivePlannerWidget::DivePlannerWidget(QWidget *parent, Qt::WindowFlags f) : QWidg
connect(CylindersModel::instance(), SIGNAL(rowsRemoved(QModelIndex, int, int)),
GasSelectionModel::instance(), SLOT(repopulate()));
connect(CylindersModel::instance(), SIGNAL(dataChanged(QModelIndex, QModelIndex)),
- plannerModel, SLOT(emitCylinderModelEdited()));
+ plannerModel, SIGNAL(cylinderModelEdited()));
connect(CylindersModel::instance(), SIGNAL(rowsInserted(QModelIndex, int, int)),
- plannerModel, SLOT(emitCylinderModelEdited()));
+ plannerModel, SIGNAL(cylinderModelEdited()));
connect(CylindersModel::instance(), SIGNAL(rowsRemoved(QModelIndex, int, int)),
- plannerModel, SLOT(emitCylinderModelEdited()));
+ plannerModel, SIGNAL(cylinderModelEdited()));
ui.tableWidget->setBtnToolTip(tr("add dive data point"));
connect(ui.startTime, SIGNAL(timeChanged(QTime)), plannerModel, SLOT(setStartTime(QTime)));
@@ -1067,11 +314,6 @@ bool DivePlannerPointsModel::recalcQ()
return recalc;
}
-void DivePlannerPointsModel::emitCylinderModelEdited()
-{
- cylinderModelEdited();
-}
-
int DivePlannerPointsModel::columnCount(const QModelIndex &parent) const
{
return COLUMNS;
@@ -1264,7 +506,9 @@ bool DivePlannerPointsModel::addGas(int o2, int he)
sanitize_gasmix(&cyl->gasmix);
/* The depth to change to that gas is given by the depth where its pO2 is 1.6 bar.
* The user should be able to change this depth manually. */
- cyl->depth.mm = 1600 * 1000 / get_o2(&mix) * 10 - 10000;
+ pressure_t modppO2;
+ modppO2.mbar = 1600;
+ cyl->depth = gas_mod(&cyl->gasmix, modppO2);
CylindersModel::instance()->setDive(stagingDive);
return true;
}
@@ -1388,7 +632,7 @@ void DivePlannerPointsModel::remove(const QModelIndex &index)
endRemoveRows();
}
-struct diveplan DivePlannerPointsModel::getDiveplan()
+struct diveplan &DivePlannerPointsModel::getDiveplan()
{
return diveplan;
}
@@ -1619,46 +863,3 @@ void DivePlannerPointsModel::createPlan()
CylindersModel::instance()->update();
plannerModel->setRecalc(oldRecalc);
}
-
-ExpanderGraphics::ExpanderGraphics(QGraphicsItem *parent) : QGraphicsRectItem(parent),
- icon(new QGraphicsPixmapItem(this)),
- increaseBtn(new Button(0, this)),
- decreaseBtn(new Button(0, this)),
- bg(new QGraphicsPixmapItem(this)),
- leftWing(new QGraphicsPixmapItem(this)),
- rightWing(new QGraphicsPixmapItem(this))
-{
- QPixmap p;
-#define CREATE(item, pixmap) \
- p = QPixmap(QString(pixmap)); \
- item->setPixmap(p);
-
- CREATE(icon, ":icon_time");
- CREATE(bg, ":round_base");
- CREATE(leftWing, ":left_wing");
- CREATE(rightWing, ":right_wing");
-#undef CREATE
-
- decreaseBtn->setPixmap(QPixmap(":arrow_down"));
- increaseBtn->setPixmap(QPixmap(":arrow_up"));
-
- setFlag(ItemIgnoresTransformations);
- leftWing->setZValue(-2);
- rightWing->setZValue(-2);
- bg->setZValue(-1);
-
- leftWing->setPos(0, 0);
- bg->setPos(leftWing->pos().x() + leftWing->boundingRect().width() - 60, 5);
- rightWing->setPos(leftWing->pos().x() + leftWing->boundingRect().width() - 20, 0);
- decreaseBtn->setPos(leftWing->pos().x(), leftWing->pos().y());
- increaseBtn->setPos(rightWing->pos().x(), rightWing->pos().y());
- icon->setPos(bg->pos().x(), bg->pos().y() - 5);
-
- //I need to bottom align the items, I need to make the 0,0 ( orgin ) to be
- // the bottom of this item, so shift everything up.
- QRectF r = childrenBoundingRect();
- Q_FOREACH(QGraphicsItem * i, childItems()) {
- i->setPos(i->pos().x(), i->pos().y() - r.height());
- }
- setScale(0.7);
-}
diff --git a/qt-ui/diveplanner.h b/qt-ui/diveplanner.h
index 506953275..4aa5f0094 100644
--- a/qt-ui/diveplanner.h
+++ b/qt-ui/diveplanner.h
@@ -55,7 +55,7 @@ public:
void editStop(int row, divedatapoint newData);
divedatapoint at(int row);
int size();
- struct diveplan getDiveplan();
+ struct diveplan &getDiveplan();
QStringList &getGasList();
QVector<QPair<int, int> > collectGases(dive *d);
int lastEnteredPoint();
@@ -80,7 +80,6 @@ slots:
void deleteTemporaryPlan();
void loadFromDive(dive *d);
void restoreBackupDive();
- void emitCylinderModelEdited();
signals:
void planCreated();
@@ -102,47 +101,16 @@ private:
QVector<QPair<int, int> > oldGases;
};
-class Button : public QObject, public QGraphicsRectItem {
- Q_OBJECT
-public:
- Button(QObject *parent = 0, QGraphicsItem *itemParent = 0);
- void setText(const QString &text);
- void setPixmap(const QPixmap &pixmap);
-
-protected:
- virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
-signals:
- void clicked();
-
-private:
- QGraphicsPixmapItem *icon;
- QGraphicsSimpleTextItem *text;
-};
-
-
-class ExpanderGraphics : public QGraphicsRectItem {
-public:
- ExpanderGraphics(QGraphicsItem *parent = 0);
-
- QGraphicsPixmapItem *icon;
- Button *increaseBtn;
- Button *decreaseBtn;
-
-private:
- QGraphicsPixmapItem *bg;
- QGraphicsPixmapItem *leftWing;
- QGraphicsPixmapItem *rightWing;
-};
-
class DiveHandler : public QObject, public QGraphicsEllipseItem {
Q_OBJECT
public:
DiveHandler();
protected:
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
-
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+signals:
+ void moved();
private:
int parentIndex();
public
@@ -151,114 +119,6 @@ slots:
void changeGas();
};
-class Ruler : public QGraphicsLineItem {
-public:
- Ruler();
- ~Ruler();
- void setMinimum(double minimum);
- void setMaximum(double maximum);
- void setTickInterval(double interval);
- void setOrientation(Qt::Orientation orientation);
- void setTickSize(qreal size);
- void updateTicks();
- double minimum() const;
- double maximum() const;
- qreal valueAt(const QPointF &p);
- qreal percentAt(const QPointF &p);
- qreal posAtValue(qreal value);
- void setColor(const QColor &color);
- void setTextColor(const QColor &color);
- int unitSystem;
-
-private:
- void eraseAll();
-
- Qt::Orientation orientation;
- QList<QGraphicsLineItem *> ticks;
- QList<QGraphicsSimpleTextItem *> labels;
- double min;
- double max;
- double interval;
- double tickSize;
- QColor textColor;
-};
-
-class DivePlannerGraphics : public QGraphicsView {
- Q_OBJECT
-public:
- DivePlannerGraphics(QWidget *parent = 0);
-
-protected:
- virtual void mouseDoubleClickEvent(QMouseEvent *event);
- virtual void showEvent(QShowEvent *event);
- virtual void resizeEvent(QResizeEvent *event);
- virtual void mouseMoveEvent(QMouseEvent *event);
- virtual void mousePressEvent(QMouseEvent *event);
- virtual void mouseReleaseEvent(QMouseEvent *event);
- bool isPointOutOfBoundaries(const QPointF &point);
- qreal fromPercent(qreal percent, Qt::Orientation orientation);
-public
-slots:
- void settingsChanged();
-private
-slots:
- void keyEscAction();
- void keyDeleteAction();
- void keyUpAction();
- void keyDownAction();
- void keyLeftAction();
- void keyRightAction();
- void increaseTime();
- void increaseDepth();
- void decreaseTime();
- void decreaseDepth();
- void drawProfile();
- void pointInserted(const QModelIndex &, int start, int end);
- void pointsRemoved(const QModelIndex &, int start, int end);
-
-private:
- void moveActiveHandler(const QPointF &MappedPos, const int pos);
-
- /* This are the lines of the plotted dive. */
- QList<QGraphicsLineItem *> lines;
-
- /* This is the user-entered handles. */
- QList<DiveHandler *> handles;
- QList<QGraphicsSimpleTextItem *> gases;
-
- /* those are the lines that follows the mouse. */
- QGraphicsLineItem *verticalLine;
- QGraphicsLineItem *horizontalLine;
-
- /* This is the handler that's being dragged. */
- DiveHandler *activeDraggedHandler;
-
- // When we start to move the handler, this pos is saved.
- // so we can revert it later.
- QPointF originalHandlerPos;
-
- /* this is the background of the dive, the blue-gradient. */
- QGraphicsPolygonItem *diveBg;
-
- /* This is the bottom ruler - the x axis, and it's associated text */
- Ruler *timeLine;
- QGraphicsSimpleTextItem *timeString;
-
- /* this is the left ruler, the y axis, and it's associated text. */
- Ruler *depthLine;
- QGraphicsSimpleTextItem *depthString;
-
- /* Buttons */
- ExpanderGraphics *depthHandler;
- ExpanderGraphics *timeHandler;
-
- int minMinutes; // this holds the minimum requested window time
- int minDepth; // this holds the minimum requested window depth
- int dpMaxTime; // this is the time of the dive calculated by the deco.
-
- friend class DiveHandler;
-};
-
#include "ui_diveplanner.h"
class DivePlannerWidget : public QWidget {
@@ -277,4 +137,7 @@ private:
Ui::DivePlanner ui;
};
+QString gasToStr(const int o2Permille, const int hePermille);
+QString dpGasToStr(const divedatapoint &p);
+
#endif // DIVEPLANNER_H
diff --git a/qt-ui/downloadfromdivecomputer.cpp b/qt-ui/downloadfromdivecomputer.cpp
index 17c2a4eaa..71f428b14 100644
--- a/qt-ui/downloadfromdivecomputer.cpp
+++ b/qt-ui/downloadfromdivecomputer.cpp
@@ -34,8 +34,7 @@ struct mydescriptor {
unsigned int model;
};
-namespace DownloadFromDcGlobal
-{
+namespace DownloadFromDcGlobal {
const char *err_string;
};
@@ -56,7 +55,6 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) :
progress_bar_text = "";
- fill_device_list();
fill_computer_list();
ui.chooseDumpFile->setEnabled(ui.dumpToFile->isChecked());
@@ -74,7 +72,6 @@ DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) :
if (default_dive_computer_product)
ui.product->setCurrentIndex(ui.product->findText(default_dive_computer_product));
}
- connect(ui.product, SIGNAL(currentIndexChanged(int)), this, SLOT(on_product_currentIndexChanged()), Qt::UniqueConnection);
if (default_dive_computer_device)
ui.device->setEditText(default_dive_computer_device);
@@ -104,7 +101,7 @@ void DownloadFromDCWidget::updateState(states state)
return;
if (state == INITIAL) {
- fill_device_list();
+ fill_device_list(DC_TYPE_OTHER);
ui.progressBar->hide();
markChildrenAsEnabled();
timer->stop();
@@ -176,6 +173,7 @@ void DownloadFromDCWidget::updateState(states state)
void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor)
{
+ int dcType = DC_TYPE_SERIAL;
QAbstractItemModel *currentModel = ui.product->model();
if (!currentModel)
return;
@@ -183,15 +181,19 @@ void DownloadFromDCWidget::on_vendor_currentIndexChanged(const QString &vendor)
productModel = new QStringListModel(productList[vendor]);
ui.product->setModel(productModel);
+ if (vendor == QString("Uemis"))
+ dcType = DC_TYPE_UEMIS;
+ fill_device_list(dcType);
+
// Memleak - but deleting gives me a crash.
//currentModel->deleteLater();
}
-void DownloadFromDCWidget::on_product_currentIndexChanged()
+void DownloadFromDCWidget::on_product_currentIndexChanged(const QString &product)
{
// Set up the DC descriptor
dc_descriptor_t *descriptor = NULL;
- descriptor = descriptorLookup[ui.vendor->currentText() + ui.product->currentText()];
+ descriptor = descriptorLookup[ui.vendor->currentText() + product];
// call dc_descriptor_get_transport to see if the dc_transport_t is DC_TRANSPORT_SERIAL
if (dc_descriptor_get_transport(descriptor) == DC_TRANSPORT_SERIAL) {
@@ -378,10 +380,20 @@ void DownloadFromDCWidget::onDownloadThreadFinished()
// down in the dive_table
for (int i = dive_table.nr - 1; i >= previousLast; i--)
delete_single_dive(i);
- } else {
+ } else if (dive_table.nr) {
+ int uniqId, idx;
+ // remember the last downloaded dive (on most dive computers this will be the chronologically
+ // first new dive) and select it again after processing all the dives
+ MainWindow::instance()->dive_list()->unselectDives();
+ uniqId = get_dive(dive_table.nr - 1)->id;
process_dives(true, preferDownloaded());
+ // after process_dives does any merging or resorting needed, we need
+ // to recreate the model for the dive list so we can select the newest dive
+ MainWindow::instance()->recreateDiveList();
+ idx = get_idx_by_uniq_id(uniqId);
+ MainWindow::instance()->dive_list()->selectDive(idx, true);
}
- } else if (currentState == CANCELLING || currentState == CANCELLED){
+ } else if (currentState == CANCELLING || currentState == CANCELLED) {
if (import_thread_cancelled) {
// walk backwards so we don't keep moving the dives
// down in the dive_table
@@ -429,11 +441,11 @@ static void fillDeviceList(const char *name, void *data)
comboBox->addItem(name);
}
-void DownloadFromDCWidget::fill_device_list()
+void DownloadFromDCWidget::fill_device_list(int dc_type)
{
int deviceIndex;
ui.device->clear();
- deviceIndex = enumerate_devices(fillDeviceList, ui.device);
+ deviceIndex = enumerate_devices(fillDeviceList, ui.device, dc_type);
if (deviceIndex >= 0)
ui.device->setCurrentIndex(deviceIndex);
}
diff --git a/qt-ui/downloadfromdivecomputer.h b/qt-ui/downloadfromdivecomputer.h
index e20ba3051..3de102bfd 100644
--- a/qt-ui/downloadfromdivecomputer.h
+++ b/qt-ui/downloadfromdivecomputer.h
@@ -42,7 +42,7 @@ slots:
void on_cancel_clicked();
void on_search_clicked();
void on_vendor_currentIndexChanged(const QString &vendor);
- void on_product_currentIndexChanged();
+ void on_product_currentIndexChanged(const QString &product);
void onDownloadThreadFinished();
void updateProgressBar();
@@ -68,7 +68,7 @@ private:
QStringListModel *vendorModel;
QStringListModel *productModel;
void fill_computer_list();
- void fill_device_list();
+ void fill_device_list(int dc_type);
QString logFile;
QString dumpFile;
QTimer *timer;
diff --git a/qt-ui/exif.cpp b/qt-ui/exif.cpp
index 82601577f..1aee47acb 100644
--- a/qt-ui/exif.cpp
+++ b/qt-ui/exif.cpp
@@ -34,8 +34,7 @@
using std::string;
-namespace
-{
+namespace {
// IF Entry
struct IFEntry {
// Raw fields
@@ -459,15 +458,15 @@ int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len)
// GPS latitude
if (format == 5 && length == 3) {
this->GeoLocation.LatComponents.degrees =
- parseEXIFRational(buf + data + tiff_header_start, alignIntel);
+ parseEXIFRational(buf + data + tiff_header_start, alignIntel);
this->GeoLocation.LatComponents.minutes =
- parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel);
+ parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel);
this->GeoLocation.LatComponents.seconds =
- parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel);
+ parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel);
this->GeoLocation.Latitude =
- this->GeoLocation.LatComponents.degrees +
- this->GeoLocation.LatComponents.minutes / 60 +
- this->GeoLocation.LatComponents.seconds / 3600;
+ this->GeoLocation.LatComponents.degrees +
+ this->GeoLocation.LatComponents.minutes / 60 +
+ this->GeoLocation.LatComponents.seconds / 3600;
if ('S' == this->GeoLocation.LatComponents.direction)
this->GeoLocation.Latitude = -this->GeoLocation.Latitude;
}
@@ -484,15 +483,15 @@ int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len)
// GPS longitude
if (format == 5 && length == 3) {
this->GeoLocation.LonComponents.degrees =
- parseEXIFRational(buf + data + tiff_header_start, alignIntel);
+ parseEXIFRational(buf + data + tiff_header_start, alignIntel);
this->GeoLocation.LonComponents.minutes =
- parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel);
+ parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel);
this->GeoLocation.LonComponents.seconds =
- parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel);
+ parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel);
this->GeoLocation.Longitude =
- this->GeoLocation.LonComponents.degrees +
- this->GeoLocation.LonComponents.minutes / 60 +
- this->GeoLocation.LonComponents.seconds / 3600;
+ this->GeoLocation.LonComponents.degrees +
+ this->GeoLocation.LonComponents.minutes / 60 +
+ this->GeoLocation.LonComponents.seconds / 3600;
if ('W' == this->GeoLocation.LonComponents.direction)
this->GeoLocation.Longitude = -this->GeoLocation.Longitude;
}
@@ -509,7 +508,7 @@ int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len)
// GPS altitude reference
if (format == 5) {
this->GeoLocation.Altitude =
- parseEXIFRational(buf + data + tiff_header_start, alignIntel);
+ parseEXIFRational(buf + data + tiff_header_start, alignIntel);
if (1 == this->GeoLocation.AltitudeRef)
this->GeoLocation.Altitude = -this->GeoLocation.Altitude;
}
diff --git a/qt-ui/globe.cpp b/qt-ui/globe.cpp
index 1101500d3..8d234194e 100644
--- a/qt-ui/globe.cpp
+++ b/qt-ui/globe.cpp
@@ -64,7 +64,7 @@ GlobeGPS::GlobeGPS(QWidget *parent) : MarbleWidget(parent),
setProjection(Marble::Spherical);
setAnimationsEnabled(true);
- Q_FOREACH(AbstractFloatItem * i, floatItems()) {
+ Q_FOREACH (AbstractFloatItem *i, floatItems()) {
i->setVisible(false);
}
@@ -142,7 +142,7 @@ void GlobeGPS::mouseClicked(qreal lon, qreal lat, GeoDataCoordinates::Unit unit)
struct dive *dive;
bool clear = !(QApplication::keyboardModifiers() & Qt::ControlModifier);
QList<int> selectedDiveIds;
- for_each_dive(idx, dive) {
+ for_each_dive (idx, dive) {
long lat_diff, lon_diff;
if (!dive_has_gps_location(dive))
continue;
@@ -175,7 +175,7 @@ void GlobeGPS::repopulateLabels()
int idx = 0;
struct dive *dive;
- for_each_dive(idx, dive) {
+ for_each_dive (idx, dive) {
if (dive_has_gps_location(dive)) {
GeoDataPlacemark *place = new GeoDataPlacemark(dive->location);
place->setCoordinate(dive->longitude.udeg / 1000000.0, dive->latitude.udeg / 1000000.0, 0, GeoDataCoordinates::Degree);
@@ -211,8 +211,7 @@ void GlobeGPS::centerOnCurrentDive()
{
struct dive *dive = current_dive;
// dive has changed, if we had the 'editingDive', hide it.
- if (messageWidget->isVisible()
- && (!dive || dive_has_gps_location(dive) || amount_selected != 1 ))
+ if (messageWidget->isVisible() && (!dive || dive_has_gps_location(dive) || amount_selected != 1))
messageWidget->hide();
editingDiveLocation = false;
@@ -222,8 +221,7 @@ void GlobeGPS::centerOnCurrentDive()
qreal longitude = dive->longitude.udeg / 1000000.0;
qreal latitude = dive->latitude.udeg / 1000000.0;
- if ((!dive_has_gps_location(dive) || MainWindow::instance()->information()->isEditing())
- && amount_selected == 1) {
+ if ((!dive_has_gps_location(dive) || MainWindow::instance()->information()->isEditing()) && amount_selected == 1) {
prepareForGetDiveCoordinates();
return;
}
@@ -261,7 +259,7 @@ void GlobeGPS::zoomOutForNoGPS()
// this is called if the dive has no GPS location.
// zoom out quite a bit to show the globe and remember that the next time
// we show a dive with GPS location we need to zoom in again
- if(fixZoomTimer->isActive())
+ if (fixZoomTimer->isActive())
fixZoomTimer->stop();
setZoom(1200, Marble::Automatic);
if (!needResetZoom) {
@@ -300,7 +298,7 @@ void GlobeGPS::changeDiveGeoPosition(qreal lon, qreal lat, GeoDataCoordinates::U
// but we keep the code here that changes the coordinates for each selected dive
int i;
struct dive *dive;
- for_each_dive(i, dive) {
+ for_each_dive (i, dive) {
if (!dive->selected)
continue;
dive->latitude.udeg = lrint(lat * 1000000.0);
@@ -341,10 +339,23 @@ void GlobeGPS::resizeEvent(QResizeEvent *event)
}
#else
-GlobeGPS::GlobeGPS(QWidget* parent) { setText("MARBLE DISABLED AT BUILD TIME"); }
-void GlobeGPS::repopulateLabels() {}
-void GlobeGPS::centerOn(dive* dive) {}
-bool GlobeGPS::eventFilter(QObject *obj, QEvent *ev) {}
-void GlobeGPS::prepareForGetDiveCoordinates(struct dive *dive) {}
-void GlobeGPS::reload() {}
+GlobeGPS::GlobeGPS(QWidget *parent)
+{
+ setText("MARBLE DISABLED AT BUILD TIME");
+}
+void GlobeGPS::repopulateLabels()
+{
+}
+void GlobeGPS::centerOnCurrentDive()
+{
+}
+bool GlobeGPS::eventFilter(QObject *obj, QEvent *ev)
+{
+}
+void GlobeGPS::prepareForGetDiveCoordinates()
+{
+}
+void GlobeGPS::reload()
+{
+}
#endif
diff --git a/qt-ui/globe.h b/qt-ui/globe.h
index add04ede4..c40eefc46 100644
--- a/qt-ui/globe.h
+++ b/qt-ui/globe.h
@@ -54,10 +54,11 @@ public:
GlobeGPS(QWidget *parent);
void reload();
void repopulateLabels();
- void centerOn(struct dive* dive);
- bool eventFilter(QObject*, QEvent*);
-public slots:
- void prepareForGetDiveCoordinates(struct dive *dive);
+ void centerOnCurrentDive();
+ bool eventFilter(QObject *, QEvent *);
+public
+slots:
+ void prepareForGetDiveCoordinates();
};
#endif // NO_MARBLE
diff --git a/qt-ui/groupedlineedit.cpp b/qt-ui/groupedlineedit.cpp
index 517623119..4ba6621e6 100644
--- a/qt-ui/groupedlineedit.cpp
+++ b/qt-ui/groupedlineedit.cpp
@@ -108,7 +108,7 @@ QStringList GroupedLineEdit::getBlockStringList()
{
QStringList retList;
Private::Block block;
- foreach(block, d->blocks)
+ foreach (block, d->blocks)
retList.append(block.text);
return retList;
}
@@ -149,10 +149,10 @@ void GroupedLineEdit::removeAllBlocks()
QSize GroupedLineEdit::sizeHint() const
{
QSize rs(
- 40,
- document()->findBlock(0).layout()->lineAt(0).height() +
- document()->documentMargin() * 2 +
- frameWidth() * 2);
+ 40,
+ document()->findBlock(0).layout()->lineAt(0).height() +
+ document()->documentMargin() * 2 +
+ frameWidth() * 2);
return rs;
}
@@ -189,15 +189,15 @@ void GroupedLineEdit::paintEvent(QPaintEvent *e)
QVectorIterator<QColor> i(d->colors);
i.toFront();
- foreach(const Private::Block & block, d->blocks) {
+ foreach (const Private::Block &block, d->blocks) {
qreal start_x = line.cursorToX(block.start, QTextLine::Trailing);
qreal end_x = line.cursorToX(block.end + 1, QTextLine::Leading);
QPainterPath path;
QRectF rectangle(
- start_x - 1.0 - double(horizontalScrollBar()->value()),
- 1.0,
- end_x - start_x + 2.0,
- double(viewport()->height() - 2));
+ start_x - 1.0 - double(horizontalScrollBar()->value()),
+ 1.0,
+ end_x - start_x + 2.0,
+ double(viewport()->height() - 2));
if (!i.hasNext())
i.toFront();
path.addRoundedRect(rectangle, 5.0, 5.0);
diff --git a/qt-ui/kmessagewidget.cpp b/qt-ui/kmessagewidget.cpp
index c21dea867..2f9ac6870 100644
--- a/qt-ui/kmessagewidget.cpp
+++ b/qt-ui/kmessagewidget.cpp
@@ -74,7 +74,7 @@ void KMessageWidgetPrivate::createLayout()
qDeleteAll(buttons);
buttons.clear();
- Q_FOREACH(QAction * action, q->actions()) {
+ Q_FOREACH (QAction *action, q->actions()) {
QToolButton *button = new QToolButton(content);
button->setDefaultAction(action);
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@ -94,7 +94,7 @@ void KMessageWidgetPrivate::createLayout()
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch();
- Q_FOREACH(QToolButton * button, buttons) {
+ Q_FOREACH (QToolButton *button, buttons) {
// For some reason, calling show() is necessary if wordwrap is true,
// otherwise the buttons do not show up. It is not needed if
// wordwrap is false.
@@ -108,7 +108,7 @@ void KMessageWidgetPrivate::createLayout()
layout->addWidget(iconLabel);
layout->addWidget(textLabel);
- Q_FOREACH(QToolButton * button, buttons) {
+ Q_FOREACH (QToolButton *button, buttons) {
layout->addWidget(button);
}
@@ -238,7 +238,7 @@ void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
bg2 = bg1.darker(110);
border = bg2.darker(110);
d->content->setStyleSheet(
- QString(".QFrame {"
+ QString(".QFrame {"
"background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
" stop: 0 %1,"
" stop: 0.1 %2,"
@@ -248,16 +248,16 @@ void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
"margin: %5px;"
"}"
".QLabel { color: %6; }").arg(bg0.name())
- .arg(bg1.name())
- .arg(bg2.name())
- .arg(border.name())
- /*
+ .arg(bg1.name())
+ .arg(bg2.name())
+ .arg(border.name())
+ /*
DefaultFrameWidth returns the size of the external margin + border width.
We know our border is 1px, so we subtract this from the frame
normal QStyle FrameWidth to get our margin
*/
- .arg(style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this) - 1)
- .arg(fg.name()));
+ .arg(style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this) - 1)
+ .arg(fg.name()));
}
QSize KMessageWidget::sizeHint() const
diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp
index 172e4e2d7..2bb261448 100644
--- a/qt-ui/maintab.cpp
+++ b/qt-ui/maintab.cpp
@@ -70,7 +70,7 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
ui.tagWidget->installEventFilter(this);
QList<QObject *> statisticsTabWidgets = ui.statisticsTab->children();
- Q_FOREACH(QObject * obj, statisticsTabWidgets) {
+ Q_FOREACH (QObject *obj, statisticsTabWidgets) {
QLabel *label = qobject_cast<QLabel *>(obj);
if (label)
label->setAlignment(Qt::AlignHCenter);
@@ -136,7 +136,7 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
" background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
" stop: 0 #E0E0E0, stop: 1 #FFFFFF);"
"}");
- Q_FOREACH(QGroupBox * box, findChildren<QGroupBox *>()) {
+ Q_FOREACH (QGroupBox *box, findChildren<QGroupBox *>()) {
box->setStyleSheet(gnomeCss);
}
}
@@ -270,10 +270,8 @@ void MainTab::enableEdition(EditMode newEditMode)
// We may be editing one or more dives here. backup everything.
struct dive *mydive;
- for (int i = 0; i < dive_table.nr; i++) {
- mydive = get_dive(i);
- if (!mydive)
- continue;
+ int i;
+ for_each_dive (i, mydive) {
if (!mydive->selected)
continue;
@@ -335,6 +333,11 @@ void MainTab::clearEquipment()
weightModel->clear();
}
+void MainTab::nextInputField(QKeyEvent *event)
+{
+ keyPressEvent(event);
+}
+
void MainTab::clearInfo()
{
ui.sacText->clear();
@@ -591,14 +594,12 @@ void MainTab::reload()
#define EDIT_SELECTED_DIVES(WHAT) \
do { \
struct dive *mydive = NULL; \
+ int _i; \
if (editMode == NONE) \
return; \
\
- for (int _i = 0; _i < dive_table.nr; _i++) { \
- mydive = get_dive(_i); \
- if (!mydive || mydive == current_dive)\
- continue; \
- if (!mydive->selected) \
+ for_each_dive (_i, mydive) { \
+ if (!mydive->selected || mydive == current_dive) \
continue; \
\
WHAT; \
@@ -666,7 +667,7 @@ void MainTab::acceptChanges()
ui.coordinates->text().trimmed().isEmpty())) {
struct dive *dive;
int i = 0;
- for_each_dive(i, dive) {
+ for_each_dive (i, dive) {
QString location(dive->location);
if (location == ui.location->text() &&
(dive->latitude.udeg || dive->longitude.udeg)) {
@@ -690,7 +691,7 @@ void MainTab::acceptChanges()
DivePlannerPointsModel::instance()->copyCylinders(curr);
} else if (editMode != ADD && cylindersModel->changed) {
mark_divelist_changed(true);
- Q_FOREACH(dive * d, notesBackup.keys()) {
+ Q_FOREACH (dive *d, notesBackup.keys()) {
for (int i = 0; i < MAX_CYLINDERS; i++) {
if (notesBackup.keys().count() > 1)
// only copy the cylinder type, none of the other values
@@ -704,7 +705,7 @@ void MainTab::acceptChanges()
if (weightModel->changed) {
mark_divelist_changed(true);
- Q_FOREACH(dive * d, notesBackup.keys()) {
+ Q_FOREACH (dive *d, notesBackup.keys()) {
for (int i = 0; i < MAX_WEIGHTSYSTEMS; i++) {
d->weightsystem[i] = multiEditEquipmentPlaceholder.weightsystem[i];
}
@@ -729,7 +730,7 @@ void MainTab::acceptChanges()
}
// each dive that was selected might have had the temperatures in its active divecomputer changed
// so re-populate the temperatures - easiest way to do this is by calling fixup_dive
- Q_FOREACH(dive * d, notesBackup.keys()) {
+ Q_FOREACH (dive *d, notesBackup.keys()) {
if (d)
fixup_dive(d);
}
@@ -746,7 +747,7 @@ void MainTab::acceptChanges()
// and then clear that flag out on the other side of the sort_table()
d->selected = true;
sort_table(&dive_table);
- for_each_dive(rememberSelected, d) {
+ for_each_dive (rememberSelected, d) {
if (d->selected) {
d->selected = false;
break;
@@ -760,6 +761,7 @@ void MainTab::acceptChanges()
editMode = NONE;
MainWindow::instance()->refreshDisplay();
MainWindow::instance()->graphics()->replot();
+ emit addDiveFinished();
} else {
editMode = NONE;
MainWindow::instance()->dive_list()->rememberSelection();
@@ -831,10 +833,8 @@ void MainTab::rejectChanges()
}
struct dive *mydive;
- for (int i = 0; i < dive_table.nr; i++) {
- mydive = get_dive(i);
- if (!mydive)
- continue;
+ int i;
+ for_each_dive (i, mydive) {
if (!mydive->selected)
continue;
@@ -862,6 +862,7 @@ void MainTab::rejectChanges()
delete_single_dive(selected_dive);
MainWindow::instance()->dive_list()->reload(DiveTripModel::CURRENT);
MainWindow::instance()->dive_list()->restoreSelection();
+ emit addDiveFinished();
}
if (selected_dive >= 0) {
multiEditEquipmentPlaceholder = *get_dive(selected_dive);
@@ -938,7 +939,7 @@ void MainTab::on_watertemp_textChanged(const QString &text)
validate_temp_field(ui.watertemp, text);
}
-void MainTab::validate_temp_field(QLineEdit *tempField,const QString &text)
+void MainTab::validate_temp_field(QLineEdit *tempField, const QString &text)
{
static bool missing_unit = false;
static bool missing_precision = false;
@@ -980,11 +981,11 @@ void MainTab::on_dateTimeEdit_dateTimeChanged(const QDateTime &datetime)
void MainTab::saveTags()
{
EDIT_SELECTED_DIVES(
- QString tag;
- taglist_free(mydive->tag_list);
- mydive->tag_list = NULL;
- foreach(tag, ui.tagWidget->getBlockStringList())
- taglist_add_tag(&mydive->tag_list, tag.toUtf8().data()););
+ QString tag;
+ taglist_free(mydive->tag_list);
+ mydive->tag_list = NULL;
+ foreach (tag, ui.tagWidget->getBlockStringList())
+ taglist_add_tag(&mydive->tag_list, tag.toUtf8().data()););
}
void MainTab::on_tagWidget_textChanged()
diff --git a/qt-ui/maintab.h b/qt-ui/maintab.h
index d201d2a47..90d3c49ef 100644
--- a/qt-ui/maintab.h
+++ b/qt-ui/maintab.h
@@ -66,6 +66,10 @@ public:
void initialUiSetup();
bool isEditing();
void updateCoordinatesText(qreal lat, qreal lon);
+ void nextInputField(QKeyEvent *event);
+signals:
+ void addDiveFinished();
+
public
slots:
void addCylinder_clicked();
@@ -81,7 +85,7 @@ slots:
void on_notes_textChanged();
void on_airtemp_textChanged(const QString &text);
void on_watertemp_textChanged(const QString &text);
- void validate_temp_field(QLineEdit *tempField,const QString &text);
+ void validate_temp_field(QLineEdit *tempField, const QString &text);
void on_dateTimeEdit_dateTimeChanged(const QDateTime &datetime);
void on_rating_valueChanged(int value);
void on_visibility_valueChanged(int value);
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 709693c30..19a16a886 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -43,6 +43,7 @@
#include "printdialog.h"
#endif
#include "divelogimportdialog.h"
+#include "divelogexportdialog.h"
#ifndef NO_USERMANUAL
#include "usermanual.h"
#endif
@@ -67,13 +68,13 @@ MainWindow::MainWindow() : QMainWindow(),
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.ListWidget, SLOT(update()));
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.ListWidget, SLOT(reloadHeaderActions()));
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.InfoWidget, SLOT(updateDiveInfo()));
- connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.divePlanner, SLOT(settingsChanged()));
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.divePlannerWidget, SLOT(settingsChanged()));
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), TankInfoModel::instance(), SLOT(update()));
connect(ui.actionRecent1, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool)));
connect(ui.actionRecent2, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool)));
connect(ui.actionRecent3, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool)));
connect(ui.actionRecent4, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool)));
+ connect(information(), SIGNAL(addDiveFinished()), ui.newProfile, SLOT(setProfileState()));
ui.mainErrorMessage->hide();
initialUiSetup();
@@ -84,10 +85,8 @@ MainWindow::MainWindow() : QMainWindow(),
ui.globe->reload();
ui.ListWidget->expand(ui.ListWidget->model()->index(0, 0));
ui.ListWidget->scrollTo(ui.ListWidget->model()->index(0, 0), QAbstractItemView::PositionAtCenter);
- ui.divePlanner->settingsChanged();
ui.divePlannerWidget->settingsChanged();
-
#ifndef ENABLE_PLANNER
ui.menuLog->removeAction(ui.actionDivePlanner);
#endif
@@ -124,14 +123,14 @@ MainWindow *MainWindow::instance()
}
// this gets called after we download dives from a divecomputer
-void MainWindow::refreshDisplay(bool recreateDiveList)
+void MainWindow::refreshDisplay(bool doRecreateDiveList)
{
showError(get_error_string());
ui.InfoWidget->reload();
TankInfoModel::instance()->update();
ui.globe->reload();
- if (recreateDiveList)
- ui.ListWidget->reload(DiveTripModel::CURRENT);
+ if (doRecreateDiveList)
+ recreateDiveList();
ui.ListWidget->setFocus();
WSInfoModel::instance()->updateInfo();
// refresh the yearly stats if the window has an instance
@@ -143,6 +142,11 @@ void MainWindow::refreshDisplay(bool recreateDiveList)
}
}
+void MainWindow::recreateDiveList()
+{
+ ui.ListWidget->reload(DiveTripModel::CURRENT);
+}
+
void MainWindow::current_dive_changed(int divenr)
{
if (divenr >= 0) {
@@ -189,7 +193,7 @@ void MainWindow::on_actionSaveAs_triggered()
file_save_as();
}
-ProfileWidget2* MainWindow::graphics() const
+ProfileWidget2 *MainWindow::graphics() const
{
return ui.newProfile;
}
@@ -273,34 +277,6 @@ void MainWindow::updateLastUsedDir(const QString &dir)
s.setValue("LastDir", dir);
}
-void MainWindow::on_actionExportUDDF_triggered()
-{
- QFileInfo fi(system_default_filename());
- QString filename = QFileDialog::getSaveFileName(this, tr("Export UDDF File as"), fi.absolutePath(),
- tr("UDDF files (*.uddf *.UDDF)"));
- if (!filename.isNull() && !filename.isEmpty())
- export_dives_xslt(filename.toUtf8(), false, "uddf-export.xslt");
-}
-
-void MainWindow::on_actionExport_CSV_triggered()
-{
- QFileInfo fi(system_default_filename());
- QString filename = QFileDialog::getSaveFileName(this, tr("Export CSV File as"), fi.absolutePath(),
- tr("CSV files (*.csv *.CSV)"));
-
- if (!filename.isNull() && !filename.isEmpty())
- export_dives_xslt(filename.toUtf8(), false, "xml2csv.xslt");
-}
-
-void MainWindow::on_actionExportHTMLworldmap_triggered()
-{
- QFileInfo fi(system_default_filename());
- QString filename = QFileDialog::getSaveFileName(this, tr("Export World Map"), fi.absolutePath(),
- tr("HTML files (*.html)"));
- if (!filename.isNull() && !filename.isEmpty())
- export_worldmap_HTML(filename.toUtf8().data());
-}
-
void MainWindow::on_actionPrint_triggered()
{
#ifndef NO_PRINTING
@@ -335,21 +311,23 @@ void MainWindow::on_actionDivePlanner_triggered()
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
DivePlannerPointsModel::instance()->clear();
CylindersModel::instance()->clear();
- for_each_dive(i,dive) {
- if(dive->selected){
+ for_each_dive (i, dive) {
+ if (dive->selected) {
DivePlannerPointsModel::instance()->copyCylindersFrom(dive);
CylindersModel::instance()->copyFromDive(dive);
break;
}
}
- ui.stackedWidget->setCurrentIndex(PLANNERPROFILE);
ui.infoPane->setCurrentIndex(PLANNERWIDGET);
}
void MainWindow::showProfile()
{
enableDcShortcuts();
- ui.stackedWidget->setCurrentIndex(PROFILE);
+ //TODO: I BROKE THIS BY COMMENTING THE LINE BELOW
+ // and I'm sleepy now, so I think I should not try to fix right away.
+ // we don't setCurrentIndex anymore, we ->setPlanState() or ->setAddState() on the ProfileView.
+ //ui.stackedWidget->setCurrentIndex(PROFILE);
ui.infoPane->setCurrentIndex(MAINTAB);
}
@@ -430,8 +408,9 @@ void MainWindow::on_actionAddDive_triggered()
ui.InfoWidget->setCurrentIndex(0);
ui.InfoWidget->updateDiveInfo(selected_dive);
ui.InfoWidget->addDiveStarted();
- ui.stackedWidget->setCurrentIndex(PLANNERPROFILE); // Planner.
ui.infoPane->setCurrentIndex(MAINTAB);
+
+ ui.newProfile->setAddState();
DivePlannerPointsModel::instance()->clear();
DivePlannerPointsModel::instance()->createSimpleDive();
ui.ListWidget->reload(DiveTripModel::CURRENT);
@@ -439,6 +418,7 @@ void MainWindow::on_actionAddDive_triggered()
void MainWindow::on_actionRenumber_triggered()
{
+ RenumberDialog::instance()->renumberOnlySelected(false);
RenumberDialog::instance()->show();
}
@@ -462,11 +442,11 @@ void MainWindow::on_actionYearlyStatistics_triggered()
yearlyStats->setMinimumWidth(600);
yearlyStats->setWindowTitle(tr("Yearly Statistics"));
yearlyStats->setWindowIcon(QIcon(":subsurface-icon"));
- QShortcut* closeKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), yearlyStats);
+ QShortcut *closeKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), yearlyStats);
connect(closeKey, SIGNAL(activated()), yearlyStats, SLOT(close()));
closeKey = new QShortcut(QKeySequence(Qt::Key_Escape), yearlyStats);
connect(closeKey, SIGNAL(activated()), yearlyStats, SLOT(close()));
- QShortcut* quitKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), yearlyStats);
+ QShortcut *quitKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), yearlyStats);
connect(quitKey, SIGNAL(activated()), this, SLOT(close()));
}
/* problem here is that without more MainWindow variables or a separate YearlyStatistics
@@ -873,7 +853,7 @@ void MainWindow::addRecentFile(const QStringList &newFiles)
}
}
- foreach(const QString & file, newFiles) {
+ foreach (const QString &file, newFiles) {
int index = files.indexOf(file);
if (index >= 0) {
@@ -881,7 +861,7 @@ void MainWindow::addRecentFile(const QStringList &newFiles)
}
}
- foreach(const QString & file, newFiles) {
+ foreach (const QString &file, newFiles) {
if (QFile::exists(file)) {
files.prepend(file);
}
@@ -929,7 +909,7 @@ void MainWindow::removeRecentFile(QStringList failedFiles)
}
}
- foreach(QString file, failedFiles)
+ foreach (QString file, failedFiles)
files.removeAll(file);
for (int c = 1; c <= 4; c++) {
@@ -965,12 +945,7 @@ void MainWindow::recentFileTriggered(bool checked)
int MainWindow::file_save_as(void)
{
QString filename;
- const char *default_filename;
-
- if (existing_filename)
- default_filename = existing_filename;
- else
- default_filename = prefs.default_filename;
+ const char *default_filename = existing_filename;
filename = QFileDialog::getSaveFileName(this, tr("Save File as"), default_filename,
tr("Subsurface XML files (*.ssrf *.xml *.XML)"));
if (filename.isNull() || filename.isEmpty())
@@ -1128,14 +1103,20 @@ void MainWindow::editCurrentDive()
if (defaultDC == "manually added dive") {
disableDcShortcuts();
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::ADD);
- ui.stackedWidget->setCurrentIndex(PLANNERPROFILE); // Planner.
+ //TODO: I BROKE THIS BY COMMENTING THE LINE BELOW
+ // and I'm sleepy now, so I think I should not try to fix right away.
+ // we don't setCurrentIndex anymore, we ->setPlanState() or ->setAddState() on the ProfileView.
+ //ui.stackedWidget->setCurrentIndex(PLANNERPROFILE); // Planner.
ui.infoPane->setCurrentIndex(MAINTAB);
DivePlannerPointsModel::instance()->loadFromDive(d);
ui.InfoWidget->enableEdition(MainTab::MANUALLY_ADDED_DIVE);
} else if (defaultDC == "planned dive") {
disableDcShortcuts();
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
- ui.stackedWidget->setCurrentIndex(PLANNERPROFILE); // Planner.
+ //TODO: I BROKE THIS BY COMMENTING THE LINE BELOW
+ // and I'm sleepy now, so I think I should not try to fix right away.
+ // we don't setCurrentIndex anymore, we ->setPlanState() or ->setAddState() on the ProfileView.
+ //ui.stackedWidget->setCurrentIndex(PLANNERPROFILE); // Planner.
ui.infoPane->setCurrentIndex(PLANNERWIDGET);
DivePlannerPointsModel::instance()->loadFromDive(d);
ui.InfoWidget->enableEdition(MainTab::MANUALLY_ADDED_DIVE);
@@ -1221,3 +1202,9 @@ void MainWindow::on_profScaled_clicked(bool triggered)
}
#undef TOOLBOX_PREF_PROFILE
+
+void MainWindow::on_actionExport_triggered()
+{
+ DiveLogExportDialog *diveLogExport = new DiveLogExportDialog(this);
+ diveLogExport->show();
+}
diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h
index 60081e957..a658fe3cc 100644
--- a/qt-ui/mainwindow.h
+++ b/qt-ui/mainwindow.h
@@ -42,10 +42,6 @@ public:
COLLAPSED,
EXPANDED
};
- enum StackWidgetIndexes {
- PROFILE,
- PLANNERPROFILE
- };
enum InfoWidgetIndexes {
MAINTAB,
PLANNERWIDGET
@@ -90,9 +86,6 @@ slots:
void on_actionSave_triggered();
void on_actionSaveAs_triggered();
void on_actionClose_triggered();
- void on_actionExportUDDF_triggered();
- void on_actionExport_CSV_triggered();
- void on_actionExportHTMLworldmap_triggered();
void on_actionPrint_triggered();
void on_actionPreferences_triggered();
void on_actionQuit_triggered();
@@ -146,13 +139,16 @@ slots:
void on_profSAC_clicked(bool triggered);
void on_profScaled_clicked(bool triggered);
+ void on_actionExport_triggered();
+
protected:
void closeEvent(QCloseEvent *);
public
slots:
void readSettings();
- void refreshDisplay(bool recreateDiveList = true);
+ void refreshDisplay(bool doRecreateDiveList = true);
+ void recreateDiveList();
void showProfile();
void editCurrentDive();
@@ -178,6 +174,4 @@ private:
UpdateManager *updateManager;
};
-MainWindow *mainWindow();
-
#endif // MAINWINDOW_H
diff --git a/qt-ui/mainwindow.ui b/qt-ui/mainwindow.ui
index 072d321fc..1fd0fa775 100644
--- a/qt-ui/mainwindow.ui
+++ b/qt-ui/mainwindow.ui
@@ -85,12 +85,8 @@
</layout>
</widget>
</widget>
- <widget class="QStackedWidget" name="stackedWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="page_5">
- <layout class="QGridLayout" name="gridLayout">
+ <widget class="QWidget" name="ProfileWidget">
+ <layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
@@ -493,29 +489,6 @@
</spacer>
</item>
</layout>
- </widget>
- <widget class="QWidget" name="page_6">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="DivePlannerGraphics" name="divePlanner"/>
- </item>
- </layout>
- </widget>
</widget>
</widget>
<widget class="QSplitter" name="listGlobeSplitter">
@@ -563,7 +536,7 @@
<x>0</x>
<y>0</y>
<width>1418</width>
- <height>25</height>
+ <height>20</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@@ -576,9 +549,7 @@
<addaction name="actionSaveAs"/>
<addaction name="separator"/>
<addaction name="actionClose"/>
- <addaction name="actionExportUDDF"/>
- <addaction name="actionExport_CSV"/>
- <addaction name="actionExportHTMLworldmap"/>
+ <addaction name="actionExport"/>
<addaction name="actionPrint"/>
<addaction name="actionPreferences"/>
<addaction name="separator"/>
@@ -702,22 +673,6 @@
<string>Ctrl+W</string>
</property>
</action>
- <action name="actionExportUDDF">
- <property name="text">
- <string>Export &amp;UDDF</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+U</string>
- </property>
- </action>
- <action name="actionExportHTMLworldmap">
- <property name="text">
- <string>Export HTML World Map</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+H</string>
- </property>
- </action>
<action name="actionPrint">
<property name="text">
<string>&amp;Print</string>
@@ -946,9 +901,15 @@
<string>&amp;Check for Updates</string>
</property>
</action>
- <action name="actionExport_CSV">
+ <action name="actionExport">
<property name="text">
- <string>Export CSV</string>
+ <string>Export</string>
+ </property>
+ <property name="toolTip">
+ <string>Export Dive Logs</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+E</string>
</property>
</action>
</widget>
diff --git a/qt-ui/modeldelegates.cpp b/qt-ui/modeldelegates.cpp
index 9073ac158..d06c6621f 100644
--- a/qt-ui/modeldelegates.cpp
+++ b/qt-ui/modeldelegates.cpp
@@ -171,7 +171,7 @@ bool ComboBoxDelegate::eventFilter(QObject *object, QEvent *event)
QKeyEvent *ev = static_cast<QKeyEvent *>(event);
if (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) {
currCombo.ignoreSelection = true;
- if (!currCombo.comboEditor->completer()->popup()->isVisible()){
+ if (!currCombo.comboEditor->completer()->popup()->isVisible()) {
currCombo.comboEditor->showPopup();
return true;
}
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index 68603e735..2bc690eb9 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -68,7 +68,7 @@ CylindersModel::CylindersModel(QObject *parent) : current(0), rows(0)
// enum {REMOVE, TYPE, SIZE, WORKINGPRESS, START, END, O2, HE, DEPTH};
setHeaderDataStrings(QStringList() << "" << tr("Type") << tr("Size") << tr("WorkPress") << tr("StartPress") << tr("EndPress") << trUtf8("O" UTF8_SUBSCRIPT_2 "%") << tr("He%")
#ifdef ENABLE_PLANNER
- << tr("Switch at")
+ << tr("Switch at")
#endif
);
}
@@ -253,11 +253,9 @@ bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, in
case O2:
if (CHANGED()) {
cyl->gasmix.o2 = string_to_fraction(vString.toUtf8().data());
- if (!cyl->gasmix.o2.permille) {
- cyl->gasmix.o2.permille = 210;
- cyl->gasmix.he.permille = 0;
- }
- cyl->depth.mm = 1600 * 1000 / cyl->gasmix.o2.permille * 10 - 10000;
+ pressure_t modppO2;
+ modppO2.mbar = 1600;
+ cyl->depth = gas_mod(&cyl->gasmix, modppO2);
changed = true;
}
break;
@@ -368,11 +366,10 @@ void CylindersModel::remove(const QModelIndex &index)
cylinder_t *cyl = &current->cylinder[index.row()];
if ((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING &&
DivePlannerPointsModel::instance()->tankInUse(cyl->gasmix.o2.permille, cyl->gasmix.he.permille)) ||
- (DivePlannerPointsModel::instance()->currentMode() == DivePlannerPointsModel::NOTHING && cyl->used))
- {
+ (DivePlannerPointsModel::instance()->currentMode() == DivePlannerPointsModel::NOTHING && cyl->used)) {
QMessageBox::warning(MainWindow::instance(), TITLE_OR_TEXT(
- tr("Cylinder cannot be removed"),
- tr("This gas in use. Only cylinders that are not used in the dive can be removed.")),
+ tr("Cylinder cannot be removed"),
+ tr("This gas in use. Only cylinders that are not used in the dive can be removed.")),
QMessageBox::Ok);
return;
}
@@ -1060,7 +1057,7 @@ static int nitrox_sort_value(struct dive *dive)
QVariant DiveItem::data(int column, int role) const
{
QVariant retVal;
- struct dive *dive = get_dive_by_diveid(diveId);
+ struct dive *dive = get_dive_by_uniq_id(diveId);
switch (role) {
case Qt::TextAlignmentRole:
@@ -1203,11 +1200,11 @@ bool DiveItem::setData(const QModelIndex &index, const QVariant &value, int role
int i;
struct dive *d;
- for_each_dive(i, d) {
+ for_each_dive (i, d) {
if (d->number == v)
return false;
}
- d = get_dive_by_diveid(diveId);
+ d = get_dive_by_uniq_id(diveId);
d->number = value.toInt();
mark_divelist_changed(true);
return true;
@@ -1215,7 +1212,7 @@ bool DiveItem::setData(const QModelIndex &index, const QVariant &value, int role
QString DiveItem::displayDate() const
{
- struct dive *dive = get_dive_by_diveid(diveId);
+ struct dive *dive = get_dive_by_uniq_id(diveId);
return get_dive_date_string(dive->when);
}
@@ -1223,7 +1220,7 @@ QString DiveItem::displayDepth() const
{
QString fract, str;
const int scale = 1000;
- struct dive *dive = get_dive_by_diveid(diveId);
+ struct dive *dive = get_dive_by_uniq_id(diveId);
if (get_units()->length == units::METERS) {
fract = QString::number((unsigned)(dive->maxdepth.mm % scale) / 100);
str = QString("%1.%2").arg((unsigned)(dive->maxdepth.mm / scale)).arg(fract, 1, QChar('0'));
@@ -1237,7 +1234,7 @@ QString DiveItem::displayDepth() const
QString DiveItem::displayDuration() const
{
int hrs, mins, secs;
- struct dive *dive = get_dive_by_diveid(diveId);
+ struct dive *dive = get_dive_by_uniq_id(diveId);
secs = dive->duration.seconds % 60;
mins = dive->duration.seconds / 60;
hrs = mins / 60;
@@ -1255,7 +1252,7 @@ QString DiveItem::displayDuration() const
QString DiveItem::displayTemperature() const
{
QString str;
- struct dive *dive = get_dive_by_diveid(diveId);
+ struct dive *dive = get_dive_by_uniq_id(diveId);
if (!dive->watertemp.mkelvin)
return str;
if (get_units()->temperature == units::CELSIUS)
@@ -1268,7 +1265,7 @@ QString DiveItem::displayTemperature() const
QString DiveItem::displaySac() const
{
QString str;
- struct dive *dive = get_dive_by_diveid(diveId);
+ struct dive *dive = get_dive_by_uniq_id(diveId);
if (get_units()->volume == units::LITER)
str = QString::number(dive->sac / 1000.0, 'f', 1).append(tr(" l/min"));
else
@@ -1284,7 +1281,7 @@ QString DiveItem::displayWeight() const
int DiveItem::weight() const
{
- struct dive *dive = get_dive_by_diveid(diveId);
+ struct dive *dive = get_dive_by_uniq_id(diveId);
weight_t tw = { total_weight(dive) };
return tw.grams;
}
@@ -1904,7 +1901,7 @@ QVariant ProfilePrintModel::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::DisplayRole: {
- struct dive *dive = get_dive_by_diveid(diveId);
+ struct dive *dive = get_dive_by_uniq_id(diveId);
struct DiveItem di;
di.diveId = diveId;
@@ -2060,7 +2057,7 @@ LanguageModel::LanguageModel(QObject *parent) : QAbstractListModel(parent)
QSettings s;
QDir d(getSubsurfaceDataPath("translations"));
QStringList result = d.entryList();
- Q_FOREACH(const QString & s, result) {
+ Q_FOREACH (const QString &s, result) {
if (s.startsWith("subsurface_") && s.endsWith(".qm")) {
languages.push_back((s == "subsurface_source.qm") ? "English" : s);
}
diff --git a/qt-ui/preferences.cpp b/qt-ui/preferences.cpp
index 47f8541db..768275d26 100644
--- a/qt-ui/preferences.cpp
+++ b/qt-ui/preferences.cpp
@@ -236,7 +236,7 @@ void PreferencesDialog::syncSettings()
// Animation
s.beginGroup("Animations");
- s.setValue("animation_speed",ui.velocitySlider->value());
+ s.setValue("animation_speed", ui.velocitySlider->value());
s.endGroup();
loadSettings();
diff --git a/qt-ui/printlayout.cpp b/qt-ui/printlayout.cpp
index c30ff9cd1..159b51822 100644
--- a/qt-ui/printlayout.cpp
+++ b/qt-ui/printlayout.cpp
@@ -98,7 +98,7 @@ int PrintLayout::estimateTotalDives() const
{
int total = 0, i = 0;
struct dive *dive;
- for_each_dive(i, dive) {
+ for_each_dive (i, dive) {
if (!dive->selected && printOptions->print_selected)
continue;
total++;
@@ -168,7 +168,7 @@ void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
yOffsetTable = scaledH - tableH;
// plot the dives at specific rows and columns on the page
- for_each_dive(i, dive) {
+ for_each_dive (i, dive) {
if (!dive->selected && printOptions->print_selected)
continue;
if (col == divesPerColumn) {
@@ -183,7 +183,7 @@ void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
// draw a profile
painter.translate((scaledW + padW) * col, (scaledH + padH) * row + yOffsetProfile);
- profile->plotDives(QList<struct dive*>() << dive);
+ profile->plotDives(QList<struct dive *>() << dive);
profile->render(&painter, QRect(0, 0, scaledW, scaledH - tableH - padPT));
painter.setTransform(origTransform);
@@ -202,7 +202,7 @@ void PrintLayout::printProfileDives(int divesPerRow, int divesPerColumn)
profile->setFrameStyle(profileFrameStyle);
profile->setPrintMode(false);
profile->resize(originalSize);
- profile->plotDives(QList<struct dive*>() << current_dive);
+ profile->plotDives(QList<struct dive *>() << current_dive);
}
/* we create a table that has a fixed height, but can stretch to fit certain width */
@@ -309,7 +309,7 @@ void PrintLayout::printTable()
addTablePrintHeadingRow(&model, row); // add one heading row
row++;
progress = 0;
- for_each_dive(i, dive) {
+ for_each_dive (i, dive) {
if (!dive->selected && printOptions->print_selected)
continue;
addTablePrintDataRow(&model, row, dive);
diff --git a/qt-ui/profile/animationfunctions.cpp b/qt-ui/profile/animationfunctions.cpp
index 05e437cf0..bd08a22ee 100644
--- a/qt-ui/profile/animationfunctions.cpp
+++ b/qt-ui/profile/animationfunctions.cpp
@@ -4,8 +4,7 @@
#include <QPropertyAnimation>
#include <QPointF>
-namespace Animations
-{
+namespace Animations {
void hide(QObject *obj)
{
@@ -26,15 +25,14 @@ namespace Animations
void moveTo(QObject *obj, qreal x, qreal y)
{
- if (prefs.animation != 0){
+ if (prefs.animation != 0) {
QPropertyAnimation *animation = new QPropertyAnimation(obj, "pos");
animation->setDuration(prefs.animation);
animation->setStartValue(obj->property("pos").toPointF());
animation->setEndValue(QPointF(x, y));
animation->start(QAbstractAnimation::DeleteWhenStopped);
- }
- else{
- obj->setProperty("pos", QPointF(x,y));
+ } else {
+ obj->setProperty("pos", QPointF(x, y));
}
}
diff --git a/qt-ui/profile/animationfunctions.h b/qt-ui/profile/animationfunctions.h
index e0338393e..9269e6dd3 100644
--- a/qt-ui/profile/animationfunctions.h
+++ b/qt-ui/profile/animationfunctions.h
@@ -6,8 +6,7 @@
class QObject;
-namespace Animations
-{
+namespace Animations {
void hide(QObject *obj);
void moveTo(QObject *obj, qreal x, qreal y);
void moveTo(QObject *obj, const QPointF &pos);
diff --git a/qt-ui/profile/divecartesianaxis.cpp b/qt-ui/profile/divecartesianaxis.cpp
index c1e93faa7..353f9880c 100644
--- a/qt-ui/profile/divecartesianaxis.cpp
+++ b/qt-ui/profile/divecartesianaxis.cpp
@@ -97,7 +97,7 @@ void DiveCartesianAxis::setTextVisible(bool arg1)
return;
}
textVisibility = arg1;
- Q_FOREACH(DiveTextItem * item, labels) {
+ Q_FOREACH (DiveTextItem *item, labels) {
item->setVisible(textVisibility);
}
}
@@ -108,7 +108,7 @@ void DiveCartesianAxis::setLinesVisible(bool arg1)
return;
}
lineVisibility = arg1;
- Q_FOREACH(DiveLineItem * item, lines) {
+ Q_FOREACH (DiveLineItem *item, lines) {
item->setVisible(lineVisibility);
}
}
@@ -161,8 +161,8 @@ void DiveCartesianAxis::updateTicks(color_indice_t color)
for (int i = 0, count = labels.size(); i < count; i++, currValueText += interval) {
qreal childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
- begin + i * stepSize :
- begin - i * stepSize;
+ begin + i * stepSize :
+ begin - i * stepSize;
labels[i]->setText(textForValue(currValueText));
if (orientation == LeftToRight || orientation == RightToLeft) {
@@ -174,8 +174,8 @@ void DiveCartesianAxis::updateTicks(color_indice_t color)
for (int i = 0, count = lines.size(); i < count; i++, currValueLine += interval) {
qreal childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
- begin + i * stepSize :
- begin - i * stepSize;
+ begin + i * stepSize :
+ begin - i * stepSize;
if (orientation == LeftToRight || orientation == RightToLeft) {
lines[i]->animateMoveTo(childPos, m.y1());
@@ -237,9 +237,9 @@ void DiveCartesianAxis::updateTicks(color_indice_t color)
}
}
- Q_FOREACH(DiveTextItem * item, labels)
+ Q_FOREACH (DiveTextItem *item, labels)
item->setVisible(textVisibility);
- Q_FOREACH(DiveLineItem * item, lines)
+ Q_FOREACH (DiveLineItem *item, lines)
item->setVisible(lineVisibility);
}
@@ -272,8 +272,8 @@ qreal DiveCartesianAxis::valueAt(const QPointF &p) const
relativePosition -= pos(); // normalize p based on the axis' offset on screen
double retValue = (orientation == LeftToRight || orientation == RightToLeft) ?
- max * (relativePosition.x() - m.x1()) / (m.x2() - m.x1()) :
- max * (relativePosition.y() - m.y1()) / (m.y2() - m.y1());
+ max * (relativePosition.x() - m.x1()) / (m.x2() - m.x1()) :
+ max * (relativePosition.y() - m.y1()) / (m.y2() - m.y1());
return retValue;
}
@@ -289,8 +289,8 @@ qreal DiveCartesianAxis::posAtValue(qreal value)
double realSize = orientation == LeftToRight || orientation == RightToLeft ?
- m.x2() - m.x1() :
- m.y2() - m.y1();
+ m.x2() - m.x1() :
+ m.y2() - m.y1();
// Inverted axis, just invert the percentage.
if (orientation == RightToLeft || orientation == BottomToTop)
@@ -298,10 +298,10 @@ qreal DiveCartesianAxis::posAtValue(qreal value)
double retValue = realSize * percent;
double adjusted =
- orientation == LeftToRight ? retValue + m.x1() + p.x() :
- orientation == RightToLeft ? retValue + m.x1() + p.x() :
- orientation == TopToBottom ? retValue + m.y1() + p.y() :
- /* entation == BottomToTop */ retValue + m.y1() + p.y();
+ orientation == LeftToRight ? retValue + m.x1() + p.x() :
+ orientation == RightToLeft ? retValue + m.x1() + p.x() :
+ orientation == TopToBottom ? retValue + m.y1() + p.y() :
+ /* entation == BottomToTop */ retValue + m.y1() + p.y();
return adjusted;
}
@@ -411,17 +411,17 @@ QString TemperatureAxis::textForValue(double value)
PartialGasPressureAxis::PartialGasPressureAxis()
{
- connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(preferencesChanged()));
+ connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
}
void PartialGasPressureAxis::setModel(DivePlotDataModel *m)
{
model = m;
- connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(preferencesChanged()));
- preferencesChanged();
+ connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(settingsChanged()));
+ settingsChanged();
}
-void PartialGasPressureAxis::preferencesChanged()
+void PartialGasPressureAxis::settingsChanged()
{
bool showPhe = prefs.pp_graphs.phe;
bool showPn2 = prefs.pp_graphs.pn2;
diff --git a/qt-ui/profile/divecartesianaxis.h b/qt-ui/profile/divecartesianaxis.h
index e5b9b7b0e..34089e614 100644
--- a/qt-ui/profile/divecartesianaxis.h
+++ b/qt-ui/profile/divecartesianaxis.h
@@ -110,7 +110,7 @@ public:
void setModel(DivePlotDataModel *model);
public
slots:
- void preferencesChanged();
+ void settingsChanged();
private:
DivePlotDataModel *model;
diff --git a/qt-ui/profile/diveplotdatamodel.cpp b/qt-ui/profile/diveplotdatamodel.cpp
index 990564fbb..2fe636a4b 100644
--- a/qt-ui/profile/diveplotdatamodel.cpp
+++ b/qt-ui/profile/diveplotdatamodel.cpp
@@ -178,7 +178,7 @@ void DivePlotDataModel::emitDataChanged()
void DivePlotDataModel::calculateDecompression()
{
- struct dive *d = get_dive_by_diveid(id());
+ struct dive *d = get_dive_by_uniq_id(id());
struct divecomputer *dc = select_dc(d);
init_decompression(d);
calculate_deco_information(d, dc, &pInfo, false);
diff --git a/qt-ui/profile/diveprofileitem.cpp b/qt-ui/profile/diveprofileitem.cpp
index 1615be87f..2a6d5ac2f 100644
--- a/qt-ui/profile/diveprofileitem.cpp
+++ b/qt-ui/profile/diveprofileitem.cpp
@@ -18,10 +18,10 @@
AbstractProfilePolygonItem::AbstractProfilePolygonItem() : QObject(), QGraphicsPolygonItem(), hAxis(NULL), vAxis(NULL), dataModel(NULL), hDataColumn(-1), vDataColumn(-1)
{
- connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(preferencesChanged()));
+ connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
}
-void AbstractProfilePolygonItem::preferencesChanged()
+void AbstractProfilePolygonItem::settingsChanged()
{
}
@@ -156,10 +156,8 @@ void DiveProfileItem::modelDataChanged(const QModelIndex &topLeft, const QModelI
if (!entry->in_deco) {
/* not in deco implies this is a safety stop, no ceiling */
p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(0)));
- } else if (entry->stopdepth < entry->depth) {
- p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(entry->stopdepth)));
} else {
- p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(entry->depth)));
+ p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(qMin(entry->stopdepth, entry->depth))));
}
}
setPolygon(p);
@@ -194,7 +192,7 @@ void DiveProfileItem::modelDataChanged(const QModelIndex &topLeft, const QModelI
}
}
-void DiveProfileItem::preferencesChanged()
+void DiveProfileItem::settingsChanged()
{
//TODO: Only modelDataChanged() here if we need to rebuild the graph ( for instance,
// if the prefs.dcceiling are enabled, but prefs.redceiling is disabled
@@ -298,7 +296,7 @@ void DiveHeartrateItem::paint(QPainter *painter, const QStyleOptionGraphicsItem
painter->drawPolyline(polygon());
}
-void DiveHeartrateItem::preferencesChanged()
+void DiveHeartrateItem::settingsChanged()
{
QSettings s;
s.beginGroup("TecDetails");
@@ -427,7 +425,7 @@ void DiveGasPressureItem::modelDataChanged(const QModelIndex &topLeft, const QMo
int last_pressure[MAX_CYLINDERS] = { 0, };
int last_time[MAX_CYLINDERS] = { 0, };
struct plot_data *entry;
- struct dive *dive = get_dive_by_diveid(dataModel->id());
+ struct dive *dive = get_dive_by_uniq_id(dataModel->id());
cyl = -1;
for (int i = 0, count = dataModel->rowCount(); i < count; i++) {
@@ -489,9 +487,9 @@ void DiveGasPressureItem::paint(QPainter *painter, const QStyleOptionGraphicsIte
QPen pen;
pen.setCosmetic(true);
pen.setWidth(2);
- struct dive *d = get_dive_by_diveid(dataModel->id());
+ struct dive *d = get_dive_by_uniq_id(dataModel->id());
struct plot_data *entry = dataModel->data().entry;
- Q_FOREACH(const QPolygonF & poly, polygons) {
+ Q_FOREACH (const QPolygonF &poly, polygons) {
for (int i = 1, count = poly.count(); i < count; i++, entry++) {
pen.setBrush(getSacColor(entry->sac, d->sac));
painter->setPen(pen);
@@ -505,7 +503,7 @@ DiveCalculatedCeiling::DiveCalculatedCeiling() : is3mIncrement(false), gradientF
gradientFactor->setY(0);
gradientFactor->setBrush(getColor(PRESSURE_TEXT));
gradientFactor->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
- preferencesChanged();
+ settingsChanged();
}
void DiveCalculatedCeiling::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
@@ -544,10 +542,10 @@ void DiveCalculatedCeiling::paint(QPainter *painter, const QStyleOptionGraphicsI
DiveCalculatedTissue::DiveCalculatedTissue()
{
- preferencesChanged();
+ settingsChanged();
}
-void DiveCalculatedTissue::preferencesChanged()
+void DiveCalculatedTissue::settingsChanged()
{
setVisible(prefs.calcalltissues && prefs.calcceiling);
}
@@ -562,11 +560,7 @@ void DiveReportedCeiling::modelDataChanged(const QModelIndex &topLeft, const QMo
plot_data *entry = dataModel->data().entry;
for (int i = 0, count = dataModel->rowCount(); i < count; i++, entry++) {
if (entry->in_deco && entry->stopdepth) {
- if (entry->stopdepth < entry->depth) {
- p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(entry->stopdepth)));
- } else {
- p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(entry->depth)));
- }
+ p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(qMin(entry->stopdepth, entry->depth))));
} else {
p.append(QPointF(hAxis->posAtValue(entry->sec), vAxis->posAtValue(0)));
}
@@ -585,7 +579,7 @@ void DiveReportedCeiling::modelDataChanged(const QModelIndex &topLeft, const QMo
setBrush(pat);
}
-void DiveCalculatedCeiling::preferencesChanged()
+void DiveCalculatedCeiling::settingsChanged()
{
if (dataModel && is3mIncrement != prefs.calcceiling3m) {
// recalculate that part.
@@ -595,7 +589,7 @@ void DiveCalculatedCeiling::preferencesChanged()
setVisible(prefs.calcceiling);
}
-void DiveReportedCeiling::preferencesChanged()
+void DiveReportedCeiling::settingsChanged()
{
setVisible(prefs.dcceiling);
}
@@ -688,9 +682,8 @@ void PartialPressureGasItem::paint(QPainter *painter, const QStyleOptionGraphics
QPolygonF poly;
painter->setPen(QPen(alertColor, pWidth));
- Q_FOREACH(const QPolygonF & poly, alertPolygons)
+ Q_FOREACH (const QPolygonF &poly, alertPolygons)
painter->drawPolyline(poly);
-
}
void PartialPressureGasItem::setThreshouldSettingsKey(const QString &threshouldSettingsKey)
@@ -702,7 +695,7 @@ PartialPressureGasItem::PartialPressureGasItem()
{
}
-void PartialPressureGasItem::preferencesChanged()
+void PartialPressureGasItem::settingsChanged()
{
QSettings s;
s.beginGroup("TecDetails");
diff --git a/qt-ui/profile/diveprofileitem.h b/qt-ui/profile/diveprofileitem.h
index c7fa59841..de0c6f0c9 100644
--- a/qt-ui/profile/diveprofileitem.h
+++ b/qt-ui/profile/diveprofileitem.h
@@ -46,7 +46,7 @@ public:
}
public
slots:
- virtual void preferencesChanged();
+ virtual void settingsChanged();
virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void modelDataRemoved(const QModelIndex &parent, int from, int to);
@@ -75,7 +75,7 @@ public:
DiveProfileItem();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void preferencesChanged();
+ virtual void settingsChanged();
void plot_depth_sample(struct plot_data *entry, QFlags<Qt::AlignmentFlag> flags, const QColor &color);
private:
@@ -100,7 +100,7 @@ public:
DiveHeartrateItem();
virtual void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
- virtual void preferencesChanged();
+ virtual void settingsChanged();
void setVisibilitySettingsKey(const QString &setVisibilitySettingsKey);
bool isVisible();
@@ -130,7 +130,7 @@ public:
DiveCalculatedCeiling();
virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- virtual void preferencesChanged();
+ virtual void settingsChanged();
private:
bool is3mIncrement;
@@ -143,14 +143,14 @@ class DiveReportedCeiling : public AbstractProfilePolygonItem {
public:
virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- virtual void preferencesChanged();
+ virtual void settingsChanged();
};
class DiveCalculatedTissue : public DiveCalculatedCeiling {
Q_OBJECT
public:
DiveCalculatedTissue();
- virtual void preferencesChanged();
+ virtual void settingsChanged();
};
class MeanDepthLine : public DiveLineItem {
@@ -176,7 +176,7 @@ public:
PartialPressureGasItem();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
virtual void modelDataChanged(const QModelIndex &topLeft = QModelIndex(), const QModelIndex &bottomRight = QModelIndex());
- virtual void preferencesChanged();
+ virtual void settingsChanged();
void setThreshouldSettingsKey(const QString &threshouldSettingsKey);
void setVisibilitySettingsKey(const QString &setVisibilitySettingsKey);
void setColors(const QColor &normalColor, const QColor &alertColor);
diff --git a/qt-ui/profile/divetooltipitem.cpp b/qt-ui/profile/divetooltipitem.cpp
index 0e68685b9..032daf6ee 100644
--- a/qt-ui/profile/divetooltipitem.cpp
+++ b/qt-ui/profile/divetooltipitem.cpp
@@ -1,5 +1,6 @@
#include "divetooltipitem.h"
#include "divecartesianaxis.h"
+#include "profilewidget2.h"
#include "profile.h"
#include "dive.h"
#include "membuffer.h"
@@ -21,7 +22,7 @@ void ToolTipItem::addToolTip(const QString &toolTip, const QIcon &icon)
{
QGraphicsPixmapItem *iconItem = 0;
double yValue = title->boundingRect().height() + SPACING;
- Q_FOREACH(ToolTip t, toolTips) {
+ Q_FOREACH (ToolTip t, toolTips) {
yValue += t.second->boundingRect().height();
}
if (!icon.isNull()) {
@@ -39,7 +40,7 @@ void ToolTipItem::addToolTip(const QString &toolTip, const QIcon &icon)
void ToolTipItem::clear()
{
- Q_FOREACH(ToolTip t, toolTips) {
+ Q_FOREACH (ToolTip t, toolTips) {
delete t.first;
delete t.second;
}
@@ -96,7 +97,7 @@ void ToolTipItem::expand()
return;
double width = 0, height = title->boundingRect().height() + SPACING;
- Q_FOREACH(ToolTip t, toolTips) {
+ Q_FOREACH (ToolTip t, toolTips) {
if (t.second->boundingRect().width() > width)
width = t.second->boundingRect().width();
height += t.second->boundingRect().height();
@@ -180,6 +181,9 @@ void ToolTipItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
persistPos();
QGraphicsPathItem::mouseReleaseEvent(event);
+ Q_FOREACH (QGraphicsItem *item, oldSelection) {
+ item->setSelected(true);
+ }
}
void ToolTipItem::persistPos()
@@ -226,8 +230,15 @@ void ToolTipItem::refresh(const QPointF &pos)
free_buffer(&mb);
QList<QGraphicsItem *> items = scene()->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder, scene()->views().first()->transform());
- Q_FOREACH(QGraphicsItem * item, items) {
+ Q_FOREACH (QGraphicsItem *item, items) {
if (!item->toolTip().isEmpty())
addToolTip(item->toolTip());
}
}
+
+void ToolTipItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ oldSelection = scene()->selectedItems();
+ scene()->clearSelection();
+ QGraphicsItem::mousePressEvent(event);
+}
diff --git a/qt-ui/profile/divetooltipitem.h b/qt-ui/profile/divetooltipitem.h
index 1f84d0664..c22287b06 100644
--- a/qt-ui/profile/divetooltipitem.h
+++ b/qt-ui/profile/divetooltipitem.h
@@ -45,6 +45,7 @@ public:
bool isExpanded() const;
void persistPos();
void readPos();
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void setTimeAxis(DiveCartesianAxis *axis);
void setPlotInfo(const plot_info &plot);
@@ -64,6 +65,8 @@ private:
DiveCartesianAxis *timeAxis;
plot_info pInfo;
int lastTime;
+
+ QList<QGraphicsItem*> oldSelection;
};
#endif // DIVETOOLTIPITEM_H
diff --git a/qt-ui/profile/profilewidget2.cpp b/qt-ui/profile/profilewidget2.cpp
index d2d01a384..2de64e71f 100644
--- a/qt-ui/profile/profilewidget2.cpp
+++ b/qt-ui/profile/profilewidget2.cpp
@@ -21,7 +21,6 @@
#include <QMenu>
#include <QContextMenuEvent>
#include <QDebug>
-#include <QSettings>
#include <QScrollBar>
#include <QtCore/qmath.h>
#include <QMessageBox>
@@ -100,6 +99,23 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent),
setEmptyState();
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
+ QAction *action = NULL;
+#define ADD_ACTION(SHORTCUT, Slot) \
+ action = new QAction(this); \
+ action->setShortcut(SHORTCUT); \
+ action->setShortcutContext(Qt::WindowShortcut); \
+ addAction(action); \
+ connect(action, SIGNAL(triggered(bool)), this, SLOT(Slot)); \
+ actionsForKeys[SHORTCUT] = action;
+
+ ADD_ACTION(Qt::Key_Escape, keyEscAction());
+ ADD_ACTION(Qt::Key_Delete, keyDeleteAction());
+ ADD_ACTION(Qt::Key_Up, keyUpAction());
+ ADD_ACTION(Qt::Key_Down, keyDownAction());
+ ADD_ACTION(Qt::Key_Left, keyLeftAction());
+ ADD_ACTION(Qt::Key_Right, keyRightAction());
+#undef ADD_ACTION
+
#ifndef QT_NO_DEBUG
QTableView *diveDepthTableView = new QTableView();
diveDepthTableView->setModel(dataModel);
@@ -107,6 +123,9 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent),
#endif
}
+#define SUBSURFACE_OBJ_DATA 1
+#define SUBSURFACE_OBJ_DC_TEXT 0x42
+
void ProfileWidget2::addItemsToScene()
{
scene()->addItem(background);
@@ -120,6 +139,11 @@ void ProfileWidget2::addItemsToScene()
scene()->addItem(temperatureItem);
scene()->addItem(gasPressureItem);
scene()->addItem(meanDepth);
+ // I cannot seem to figure out if an object that I find with itemAt() on the scene
+ // is the object I am looking for - my guess is there's a simple way in Qt to do that
+ // but nothing I tried worked.
+ // so instead this adds a special magic key/value pair to the object to mark it
+ diveComputerText->setData(SUBSURFACE_OBJ_DATA, SUBSURFACE_OBJ_DC_TEXT);
scene()->addItem(diveComputerText);
scene()->addItem(diveCeiling);
scene()->addItem(reportedCeiling);
@@ -131,7 +155,7 @@ void ProfileWidget2::addItemsToScene()
scene()->addItem(rulerItem);
scene()->addItem(rulerItem->sourceNode());
scene()->addItem(rulerItem->destNode());
- Q_FOREACH(DiveCalculatedTissue * tissue, allTissues) {
+ Q_FOREACH (DiveCalculatedTissue *tissue, allTissues) {
scene()->addItem(tissue);
}
}
@@ -196,7 +220,7 @@ void ProfileWidget2::setupItemOnScene()
setupItem(temperatureItem, timeAxis, temperatureAxis, dataModel, DivePlotDataModel::TEMPERATURE, DivePlotDataModel::TIME, 1);
setupItem(heartBeatItem, timeAxis, heartBeatAxis, dataModel, DivePlotDataModel::HEARTBEAT, DivePlotDataModel::TIME, 1);
heartBeatItem->setVisibilitySettingsKey("hrgraph");
- heartBeatItem->preferencesChanged();
+ heartBeatItem->settingsChanged();
setupItem(diveProfileItem, timeAxis, profileYAxis, dataModel, DivePlotDataModel::DEPTH, DivePlotDataModel::TIME, 0);
#define CREATE_PP_GAS(ITEM, VERTICAL_COLUMN, COLOR, COLOR_ALERT, THRESHOULD_SETTINGS, VISIBILITY_SETTINGS) \
@@ -204,7 +228,7 @@ void ProfileWidget2::setupItemOnScene()
ITEM->setThreshouldSettingsKey(THRESHOULD_SETTINGS); \
ITEM->setVisibilitySettingsKey(VISIBILITY_SETTINGS); \
ITEM->setColors(getColor(COLOR, isGrayscale), getColor(COLOR_ALERT, isGrayscale)); \
- ITEM->preferencesChanged(); \
+ ITEM->settingsChanged(); \
ITEM->setZValue(99);
CREATE_PP_GAS(pn2GasItem, PN2, PN2, PN2_ALERT, "pn2threshold", "pn2graph");
@@ -227,7 +251,7 @@ void ProfileWidget2::replot()
{
int diveId = dataModel->id();
dataModel->clear();
- plotDives(QList<dive *>() << get_dive_by_diveid(diveId));
+ plotDives(QList<dive *>() << get_dive_by_uniq_id(diveId));
}
void ProfileWidget2::setupItemSizes()
@@ -336,6 +360,19 @@ void ProfileWidget2::plotDives(QList<dive *> dives)
if (!d)
return;
+ //TODO: This is a temporary hack to help me understand the Planner.
+ // It seems that each time the 'createTemporaryPlan' runs, a new
+ // dive is created, and thus, we can plot that. hm...
+ if (currentState == ADD) {
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ plannerModel->createTemporaryPlan();
+ if (!plannerModel->getDiveplan().dp) {
+ plannerModel->deleteTemporaryPlan();
+ return;
+ }
+ }
+ //END
+
int animSpeedBackup = -1;
if (firstCall && MainWindow::instance()->filesFromCommandLine()) {
animSpeedBackup = prefs.animation;
@@ -352,12 +389,7 @@ void ProfileWidget2::plotDives(QList<dive *> dives)
// reset some item visibility on printMode changes
toolTipItem->setVisible(!printMode);
- QSettings s;
- s.beginGroup("TecDetails");
- const bool rulerVisible = s.value("rulergraph", false).toBool() && !printMode;
- rulerItem->setVisible(rulerVisible);
- rulerItem->sourceNode()->setVisible(rulerVisible);
- rulerItem->destNode()->setVisible(rulerVisible);
+ rulerItem->setVisible(prefs.rulergraph && !printMode);
// No need to do this again if we are already showing the same dive
// computer of the same dive, so we check the unique id of the dive
@@ -368,7 +400,8 @@ void ProfileWidget2::plotDives(QList<dive *> dives)
if (d->id == dataModel->id() && dc_number == dataModel->dcShown())
return;
- setProfileState();
+ if (currentState == EMPTY)
+ setProfileState();
// next get the dive computer structure - if there are no samples
// let's create a fake profile that's somewhat reasonable for the
@@ -463,14 +496,24 @@ void ProfileWidget2::plotDives(QList<dive *> dives)
event = event->next;
}
// Only set visible the events that should be visible
- Q_FOREACH(DiveEventItem * event, eventItems) {
+ Q_FOREACH (DiveEventItem *event, eventItems) {
event->setVisible(!event->shouldBeHidden());
// qDebug() << event->getEvent()->name << "@" << event->getEvent()->time.seconds << "is hidden:" << event->isHidden();
}
- diveComputerText->setText(currentdc->model);
+ QString dcText = currentdc->model;
+ int nr;
+ if ((nr = number_of_computers(current_dive)) > 1)
+ dcText += tr(" (#%1 of %2)").arg(dc_number + 1).arg(nr);
+ diveComputerText->setText(dcText);
if (MainWindow::instance()->filesFromCommandLine() && animSpeedBackup != -1) {
prefs.animation = animSpeedBackup;
}
+
+ if (currentState == ADD) { // TODO: figure a way to move this from here.
+ repositionDiveHandlers();
+ DivePlannerPointsModel *model = DivePlannerPointsModel::instance();
+ model->deleteTemporaryPlan();
+ }
}
void ProfileWidget2::settingsChanged()
@@ -492,16 +535,6 @@ void ProfileWidget2::settingsChanged()
needReplot = true;
}
- if (currentState == PROFILE) {
- rulerItem->setVisible(prefs.rulergraph);
- rulerItem->destNode()->setVisible(prefs.rulergraph);
- rulerItem->sourceNode()->setVisible(prefs.rulergraph);
- needReplot = true;
- } else {
- rulerItem->setVisible(false);
- rulerItem->destNode()->setVisible(false);
- rulerItem->sourceNode()->setVisible(false);
- }
if (needReplot)
replot();
}
@@ -543,6 +576,30 @@ void ProfileWidget2::wheelEvent(QWheelEvent *event)
toolTipItem->setPos(mapToScene(toolTipPos));
}
+void ProfileWidget2::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (currentState == PLAN || currentState == ADD) {
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ QPointF mappedPos = mapToScene(event->pos());
+ if (isPointOutOfBoundaries(mappedPos))
+ return;
+
+ int minutes = rint(timeAxis->valueAt(mappedPos) / 60);
+ int milimeters = rint(profileYAxis->valueAt(mappedPos) / M_OR_FT(1, 1)) * M_OR_FT(1, 1);
+ plannerModel->addStop(milimeters, minutes * 60, -1, 0, 0, true);
+ }
+}
+
+bool ProfileWidget2::isPointOutOfBoundaries(const QPointF &point) const
+{
+ double xpos = timeAxis->valueAt(point);
+ double ypos = profileYAxis->valueAt(point);
+ return (xpos > timeAxis->maximum() ||
+ xpos < timeAxis->minimum() ||
+ ypos > profileYAxis->maximum() ||
+ ypos < profileYAxis->minimum());
+}
+
void ProfileWidget2::scrollViewTo(const QPoint &pos)
{
/* since we cannot use translate() directly on the scene we hack on
@@ -585,6 +642,8 @@ void ProfileWidget2::setEmptyState()
if (currentState == EMPTY)
return;
+ disconnectTemporaryConnections();
+ setBackgroundBrush(getColor(::BACKGROUND, isGrayscale));
dataModel->clear();
currentState = EMPTY;
MainWindow::instance()->setToolButtonsEnabled(false);
@@ -604,15 +663,13 @@ void ProfileWidget2::setEmptyState()
diveCeiling->setVisible(false);
reportedCeiling->setVisible(false);
rulerItem->setVisible(false);
- rulerItem->destNode()->setVisible(false);
- rulerItem->sourceNode()->setVisible(false);
pn2GasItem->setVisible(false);
po2GasItem->setVisible(false);
pheGasItem->setVisible(false);
- Q_FOREACH(DiveCalculatedTissue * tissue, allTissues) {
+ Q_FOREACH (DiveCalculatedTissue *tissue, allTissues) {
tissue->setVisible(false);
}
- Q_FOREACH(DiveEventItem * event, eventItems) {
+ Q_FOREACH (DiveEventItem *event, eventItems) {
event->setVisible(false);
}
}
@@ -623,6 +680,10 @@ void ProfileWidget2::setProfileState()
if (currentState == PROFILE)
return;
+ disconnectTemporaryConnections();
+ //TODO: Move the DC handling to another method.
+ MainWindow::instance()->enableDcShortcuts();
+
currentState = PROFILE;
MainWindow::instance()->setToolButtonsEnabled(true);
toolTipItem->readPos();
@@ -670,16 +731,50 @@ void ProfileWidget2::setProfileState()
reportedCeiling->setVisible(prefs.dcceiling);
if (prefs.calcalltissues) {
- Q_FOREACH(DiveCalculatedTissue * tissue, allTissues) {
+ Q_FOREACH (DiveCalculatedTissue *tissue, allTissues) {
tissue->setVisible(true);
}
}
- QSettings s;
- s.beginGroup("TecDetails");
- bool rulerVisible = s.value("rulergraph", false).toBool();
- rulerItem->setVisible(rulerVisible);
- rulerItem->destNode()->setVisible(rulerVisible);
- rulerItem->sourceNode()->setVisible(rulerVisible);
+ rulerItem->setVisible(prefs.rulergraph);
+}
+
+void ProfileWidget2::setAddState()
+{
+ if (currentState == ADD)
+ return;
+
+ setProfileState();
+ disconnectTemporaryConnections();
+ //TODO: Move this method to another place, shouldn't be on mainwindow.
+ MainWindow::instance()->disableDcShortcuts();
+ actionsForKeys[Qt::Key_Left]->setShortcut(Qt::Key_Left);
+ actionsForKeys[Qt::Key_Right]->setShortcut(Qt::Key_Right);
+ actionsForKeys[Qt::Key_Up]->setShortcut(Qt::Key_Up);
+ actionsForKeys[Qt::Key_Down]->setShortcut(Qt::Key_Down);
+ actionsForKeys[Qt::Key_Escape]->setShortcut(Qt::Key_Escape);
+ actionsForKeys[Qt::Key_Delete]->setShortcut(Qt::Key_Delete);
+
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ connect(plannerModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(replot()));
+ connect(plannerModel, SIGNAL(cylinderModelEdited()), this, SLOT(replot()));
+ connect(plannerModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
+ this, SLOT(pointInserted(const QModelIndex &, int, int)));
+ connect(plannerModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
+ this, SLOT(pointsRemoved(const QModelIndex &, int, int)));
+ /* show the same stuff that the profile shows. */
+ currentState = ADD; /* enable the add state. */
+ setBackgroundBrush(QColor(Qt::blue).light());
+}
+
+void ProfileWidget2::setPlanState()
+{
+ if (currentState == PLAN)
+ return;
+ setProfileState();
+ disconnectTemporaryConnections();
+ /* show the same stuff that the profile shows. */
+ currentState = PLAN; /* enable the add state. */
+ setBackgroundBrush(QColor(Qt::green).light());
}
extern struct ev_select *ev_namelist;
@@ -688,9 +783,36 @@ extern int evn_used;
void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
{
- if (selected_dive == -1)
+ if (currentState == ADD || currentState == PLAN) {
+ QGraphicsView::contextMenuEvent(event);
return;
+ }
QMenu m;
+ bool isDCName = false;
+ if (selected_dive == -1)
+ return;
+ // figure out if we are ontop of the dive computer name in the profile
+ QGraphicsItem *sceneItem = itemAt(mapFromGlobal(event->globalPos()));
+ if (sceneItem) {
+ QGraphicsItem *parentItem = sceneItem;
+ while (parentItem) {
+ if (parentItem->data(SUBSURFACE_OBJ_DATA) == SUBSURFACE_OBJ_DC_TEXT) {
+ isDCName = true;
+ break;
+ }
+ parentItem = parentItem->parentItem();
+ }
+ if (isDCName) {
+ if (dc_number == 0)
+ return;
+ // create menu to show when right clicking on dive computer name
+ m.addAction(tr("Make first divecomputer"), this, SLOT(makeFirstDC()));
+ m.exec(event->globalPos());
+ // don't show the regular profile context menu
+ return;
+ }
+ }
+ // create the profile context menu
QMenu *gasChange = m.addMenu(tr("Add Gas Change"));
GasSelectionModel *model = GasSelectionModel::instance();
model->repopulate();
@@ -704,7 +826,6 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
}
QAction *action = m.addAction(tr("Add Bookmark"), this, SLOT(addBookmark()));
action->setData(event->globalPos());
- QGraphicsItem *sceneItem = itemAt(mapFromGlobal(event->globalPos()));
if (DiveEventItem *item = dynamic_cast<DiveEventItem *>(sceneItem)) {
action = new QAction(&m);
action->setText(tr("Remove Event"));
@@ -738,6 +859,18 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
m.exec(event->globalPos());
}
+void ProfileWidget2::makeFirstDC()
+{
+ make_first_dc();
+ mark_divelist_changed(true);
+ // this is now the first DC, so we need to redraw the profile and refresh the dive list
+ // (and no, it's not just enough to rewrite the text - the first DC is special so values in the
+ // dive list may change).
+ // As a side benefit, this returns focus to the dive list.
+ dc_number = 0;
+ MainWindow::instance()->refreshDisplay();
+}
+
void ProfileWidget2::hideEvents()
{
QAction *action = qobject_cast<QAction *>(sender());
@@ -749,14 +882,18 @@ void ProfileWidget2::hideEvents()
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
if (event->name) {
for (int i = 0; i < evn_used; i++) {
- if (!strcmp(event->name, ev_namelist[i].ev_name)) {
+ if (same_string(event->name, ev_namelist[i].ev_name)) {
ev_namelist[i].plot_ev = false;
break;
}
}
+ Q_FOREACH (DiveEventItem *evItem, eventItems) {
+ if (same_string(evItem->getEvent()->name, event->name))
+ evItem->hide();
+ }
+ } else {
+ item->hide();
}
- item->hide();
- replot();
}
}
@@ -765,7 +902,8 @@ void ProfileWidget2::unhideEvents()
for (int i = 0; i < evn_used; i++) {
ev_namelist[i].plot_ev = true;
}
- replot();
+ Q_FOREACH (DiveEventItem *item, eventItems)
+ item->show();
}
void ProfileWidget2::removeEvent()
@@ -775,16 +913,10 @@ void ProfileWidget2::removeEvent()
struct event *event = item->getEvent();
if (QMessageBox::question(MainWindow::instance(), TITLE_OR_TEXT(
- tr("Remove the selected event?"),
- tr("%1 @ %2:%3").arg(event->name).arg(event->time.seconds / 60).arg(event->time.seconds % 60, 2, 10, QChar('0'))),
+ tr("Remove the selected event?"),
+ tr("%1 @ %2:%3").arg(event->name).arg(event->time.seconds / 60).arg(event->time.seconds % 60, 2, 10, QChar('0'))),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
- struct event **ep = &current_dc->events;
- while (ep && *ep != event)
- ep = &(*ep)->next;
- if (ep) {
- *ep = event->next;
- free(event);
- }
+ remove_event(event);
mark_divelist_changed(true);
replot();
}
@@ -808,7 +940,7 @@ void ProfileWidget2::changeGas()
int diveId = dataModel->id();
int o2, he;
int seconds = timeAxis->valueAt(scenePos);
- struct dive *d = get_dive_by_diveid(diveId);
+ struct dive *d = get_dive_by_uniq_id(diveId);
validate_gas(gas.toUtf8().constData(), &o2, &he);
add_gas_switch_event(d, get_dive_dc(d, diveComputer), seconds, get_gasidx(d, o2, he));
@@ -846,3 +978,248 @@ void ProfileWidget2::editName()
}
replot();
}
+
+void ProfileWidget2::disconnectTemporaryConnections()
+{
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ disconnect(plannerModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(replot()));
+ disconnect(plannerModel, SIGNAL(cylinderModelEdited()), this, SLOT(replot()));
+
+ disconnect(plannerModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
+ this, SLOT(pointInserted(const QModelIndex &, int, int)));
+ disconnect(plannerModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
+ this, SLOT(pointsRemoved(const QModelIndex &, int, int)));
+
+
+ Q_FOREACH (QAction *action, actionsForKeys.values()) {
+ action->setShortcut(QKeySequence());
+ }
+}
+
+void ProfileWidget2::pointInserted(const QModelIndex &parent, int start, int end)
+{
+ DiveHandler *item = new DiveHandler();
+ scene()->addItem(item);
+ handles << item;
+
+ connect(item, SIGNAL(moved()), this, SLOT(recreatePlannedDive()));
+ QGraphicsSimpleTextItem *gasChooseBtn = new QGraphicsSimpleTextItem();
+ scene()->addItem(gasChooseBtn);
+ gasChooseBtn->setZValue(10);
+ gasChooseBtn->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ gases << gasChooseBtn;
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ if (plannerModel->recalcQ())
+ replot();
+}
+
+void ProfileWidget2::pointsRemoved(const QModelIndex &, int start, int end)
+{ // start and end are inclusive.
+ int num = (end - start) + 1;
+ for (int i = num; i != 0; i--) {
+ delete handles.back();
+ handles.pop_back();
+ delete gases.back();
+ gases.pop_back();
+ }
+ scene()->clearSelection();
+ replot();
+}
+
+void ProfileWidget2::repositionDiveHandlers()
+{
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ // Re-position the user generated dive handlers
+ int last = 0;
+ for (int i = 0; i < plannerModel->rowCount(); i++) {
+ struct divedatapoint datapoint = plannerModel->at(i);
+ if (datapoint.time == 0) // those are the magic entries for tanks
+ continue;
+ DiveHandler *h = handles.at(i);
+ h->setPos(timeAxis->posAtValue(datapoint.time), profileYAxis->posAtValue(datapoint.depth));
+ QPointF p1 = (last == i) ? QPointF(timeAxis->posAtValue(0), profileYAxis->posAtValue(0)) : handles[last]->pos();
+ QPointF p2 = handles[i]->pos();
+ QLineF line(p1, p2);
+ QPointF pos = line.pointAt(0.5);
+ gases[i]->setPos(pos);
+ gases[i]->setText(dpGasToStr(plannerModel->at(i)));
+ last = i;
+ }
+}
+
+int ProfileWidget2::fixHandlerIndex(DiveHandler *activeHandler)
+{
+ int index = handles.indexOf(activeHandler);
+ if (index > 0 && index < handles.count() - 1) {
+ DiveHandler *before = handles[index - 1];
+ if (before->pos().x() > activeHandler->pos().x()) {
+ handles.swap(index, index - 1);
+ return index - 1;
+ }
+ DiveHandler *after = handles[index + 1];
+ if (after->pos().x() < activeHandler->pos().x()) {
+ handles.swap(index, index + 1);
+ return index + 1;
+ }
+ }
+ return index;
+}
+
+void ProfileWidget2::recreatePlannedDive()
+{
+ DiveHandler *activeHandler = qobject_cast<DiveHandler *>(sender());
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ int index = fixHandlerIndex(activeHandler);
+ int mintime = 0, maxtime = (timeAxis->maximum() + 10) * 60;
+ if (index > 0)
+ mintime = plannerModel->at(index - 1).time;
+ if (index < plannerModel->size() - 1)
+ maxtime = plannerModel->at(index + 1).time;
+
+ int minutes = rint(timeAxis->valueAt(activeHandler->pos()) / 60);
+ if (minutes * 60 <= mintime || minutes * 60 >= maxtime)
+ return;
+
+ divedatapoint data = plannerModel->at(index);
+ data.depth = rint(profileYAxis->valueAt(activeHandler->pos()) / M_OR_FT(1, 1)) * M_OR_FT(1, 1);
+ data.time = rint(timeAxis->valueAt(activeHandler->pos()));
+
+ plannerModel->editStop(index, data);
+}
+
+void ProfileWidget2::keyDownAction()
+{
+ if (currentState != ADD && currentState != PLAN)
+ return;
+
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
+ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
+ int row = handles.indexOf(handler);
+ divedatapoint dp = plannerModel->at(row);
+ if (dp.depth >= profileYAxis->maximum())
+ continue;
+
+ dp.depth += M_OR_FT(1, 5);
+ plannerModel->editStop(row, dp);
+ }
+ }
+}
+
+void ProfileWidget2::keyUpAction()
+{
+ if (currentState != ADD && currentState != PLAN)
+ return;
+
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
+ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
+ int row = handles.indexOf(handler);
+ divedatapoint dp = plannerModel->at(row);
+
+ if (dp.depth <= 0)
+ continue;
+
+ dp.depth -= M_OR_FT(1, 5);
+ plannerModel->editStop(row, dp);
+ }
+ }
+}
+
+void ProfileWidget2::keyLeftAction()
+{
+ if (currentState != ADD && currentState != PLAN)
+ return;
+
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
+ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
+ int row = handles.indexOf(handler);
+ divedatapoint dp = plannerModel->at(row);
+
+ if (dp.time / 60 <= 0)
+ continue;
+
+ // don't overlap positions.
+ // maybe this is a good place for a 'goto'?
+ double xpos = timeAxis->posAtValue((dp.time - 60) / 60);
+ bool nextStep = false;
+ Q_FOREACH (DiveHandler *h, handles) {
+ if (IS_FP_SAME(h->pos().x(), xpos)) {
+ nextStep = true;
+ break;
+ }
+ }
+ if (nextStep)
+ continue;
+
+ dp.time -= 60;
+ plannerModel->editStop(row, dp);
+ }
+ }
+}
+
+void ProfileWidget2::keyRightAction()
+{
+ if (currentState != ADD && currentState != PLAN)
+ return;
+
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
+ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
+ int row = handles.indexOf(handler);
+ divedatapoint dp = plannerModel->at(row);
+ if (dp.time / 60 >= timeAxis->maximum())
+ continue;
+
+ // don't overlap positions.
+ // maybe this is a good place for a 'goto'?
+ double xpos = timeAxis->posAtValue((dp.time + 60) / 60);
+ bool nextStep = false;
+ Q_FOREACH (DiveHandler *h, handles) {
+ if (IS_FP_SAME(h->pos().x(), xpos)) {
+ nextStep = true;
+ break;
+ }
+ }
+ if (nextStep)
+ continue;
+
+ dp.time += 60;
+ plannerModel->editStop(row, dp);
+ }
+ }
+}
+
+void ProfileWidget2::keyDeleteAction()
+{
+ if (currentState != ADD && currentState != PLAN)
+ return;
+
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ int selCount = scene()->selectedItems().count();
+ if (selCount) {
+ QVector<int> selectedIndexes;
+ Q_FOREACH (QGraphicsItem *i, scene()->selectedItems()) {
+ if (DiveHandler *handler = qgraphicsitem_cast<DiveHandler *>(i)) {
+ selectedIndexes.push_back(handles.indexOf(handler));
+ }
+ }
+ plannerModel->removeSelectedPoints(selectedIndexes);
+ }
+}
+
+void ProfileWidget2::keyEscAction()
+{
+ if (currentState != ADD && currentState != PLAN)
+ return;
+
+ if (scene()->selectedItems().count()) {
+ scene()->clearSelection();
+ return;
+ }
+
+ DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance();
+ if (plannerModel->isPlanner())
+ plannerModel->cancelPlan();
+}
diff --git a/qt-ui/profile/profilewidget2.h b/qt-ui/profile/profilewidget2.h
index d00cb26c1..3c3d86d01 100644
--- a/qt-ui/profile/profilewidget2.h
+++ b/qt-ui/profile/profilewidget2.h
@@ -40,6 +40,9 @@ class DiveCalculatedTissue;
class PartialPressureGasItem;
class PartialGasPressureAxis;
class AbstractProfilePolygonItem;
+class DiveHandler;
+class QGraphicsSimpleTextItem;
+class QModelIndex;
class ProfileWidget2 : public QGraphicsView {
Q_OBJECT
@@ -64,28 +67,47 @@ public:
ProfileWidget2(QWidget *parent = 0);
void plotDives(QList<dive *> dives);
- void replot();
virtual bool eventFilter(QObject *, QEvent *);
void setupItem(AbstractProfilePolygonItem *item, DiveCartesianAxis *hAxis, DiveCartesianAxis *vAxis, DivePlotDataModel *model, int vData, int hData, int zValue);
void setPrintMode(bool mode, bool grayscale = false);
+ bool isPointOutOfBoundaries(const QPointF &point) const;
+ State currentState;
public
slots: // Necessary to call from QAction's signals.
void settingsChanged();
void setEmptyState();
void setProfileState();
+ void setPlanState();
+ void setAddState();
void changeGas();
void addBookmark();
void hideEvents();
void unhideEvents();
void removeEvent();
void editName();
+ void makeFirstDC();
+ void pointInserted(const QModelIndex &parent, int start, int end);
+ void pointsRemoved(const QModelIndex &, int start, int end);
+ void replot();
+
+ /* this is called for every move on the handlers. maybe we can speed up this a bit? */
+ void recreatePlannedDive();
+
+ /* key press handlers */
+ void keyEscAction();
+ void keyDeleteAction();
+ void keyUpAction();
+ void keyDownAction();
+ void keyLeftAction();
+ void keyRightAction();
protected:
virtual void resizeEvent(QResizeEvent *event);
virtual void wheelEvent(QWheelEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void contextMenuEvent(QContextMenuEvent *event);
+ virtual void mouseDoubleClickEvent(QMouseEvent *event);
private: /*methods*/
void fixBackgroundPos();
@@ -94,10 +116,10 @@ private: /*methods*/
void setupItemSizes();
void addItemsToScene();
void setupItemOnScene();
+ void disconnectTemporaryConnections();
private:
DivePlotDataModel *dataModel;
- State currentState;
int zoomLevel;
qreal zoomFactor;
DivePixmapItem *background;
@@ -130,6 +152,14 @@ private:
RulerItem2 *rulerItem;
bool isGrayscale;
bool printMode;
+
+ //specifics for ADD and PLAN
+ QList<DiveHandler *> handles;
+ QList<QGraphicsSimpleTextItem *> gases;
+ void repositionDiveHandlers();
+ int fixHandlerIndex(DiveHandler *activeHandler);
+ friend class DiveHandler;
+ QHash<Qt::Key, QAction *> actionsForKeys;
};
#endif // PROFILEWIDGET2_H
diff --git a/qt-ui/profile/ruleritem.cpp b/qt-ui/profile/ruleritem.cpp
index 768d912e9..0f2a24a80 100644
--- a/qt-ui/profile/ruleritem.cpp
+++ b/qt-ui/profile/ruleritem.cpp
@@ -1,5 +1,7 @@
#include "ruleritem.h"
#include "divetextitem.h"
+#include "profilewidget2.h"
+#include "../preferences.h"
#include <QFont>
#include <QFontMetrics>
@@ -24,7 +26,7 @@ RulerNodeItem2::RulerNodeItem2() : entry(NULL), ruler(NULL)
setFlag(ItemIgnoresTransformations);
}
-void RulerNodeItem2::setPlotInfo(plot_info& info)
+void RulerNodeItem2::setPlotInfo(plot_info &info)
{
pInfo = info;
entry = pInfo.entry;
@@ -79,6 +81,15 @@ RulerItem2::RulerItem2() : source(new RulerNodeItem2()),
textItemBack->setPen(QColor(Qt::white));
textItemBack->setFlag(QGraphicsItem::ItemIgnoresTransformations);
setPen(QPen(QColor(Qt::black), 0.0));
+ connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
+}
+
+void RulerItem2::settingsChanged()
+{
+ ProfileWidget2 *profWidget = NULL;
+ if (scene() && scene()->views().count())
+ profWidget = qobject_cast<ProfileWidget2 *>(scene()->views().first());
+ setVisible(profWidget->currentState == ProfileWidget2::PROFILE ? prefs.rulergraph : false);
}
void RulerItem2::recalculate()
@@ -157,3 +168,10 @@ void RulerItem2::setAxis(DiveCartesianAxis *time, DiveCartesianAxis *depth)
source->timeAxis = time;
recalculate();
}
+
+void RulerItem2::setVisible(bool visible)
+{
+ QGraphicsLineItem::setVisible(visible);
+ source->setVisible(visible);
+ dest->setVisible(visible);
+}
diff --git a/qt-ui/profile/ruleritem.h b/qt-ui/profile/ruleritem.h
index 7bfc63eee..3eda33225 100644
--- a/qt-ui/profile/ruleritem.h
+++ b/qt-ui/profile/ruleritem.h
@@ -17,7 +17,7 @@ class RulerNodeItem2 : public QObject, public QGraphicsEllipseItem {
public:
explicit RulerNodeItem2();
void setRuler(RulerItem2 *r);
- void setPlotInfo(struct plot_info& info);
+ void setPlotInfo(struct plot_info &info);
void recalculate();
protected:
@@ -31,7 +31,8 @@ private:
DiveCartesianAxis *depthAxis;
};
-class RulerItem2 : public QGraphicsLineItem {
+class RulerItem2 : public QObject, public QGraphicsLineItem {
+ Q_OBJECT
public:
explicit RulerItem2();
void recalculate();
@@ -40,6 +41,11 @@ public:
RulerNodeItem2 *sourceNode() const;
RulerNodeItem2 *destNode() const;
void setAxis(DiveCartesianAxis *time, DiveCartesianAxis *depth);
+ void setVisible(bool visible);
+
+public
+slots:
+ void settingsChanged();
private:
struct plot_info pInfo;
diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp
index 8932baf15..99e0ba362 100644
--- a/qt-ui/simplewidgets.cpp
+++ b/qt-ui/simplewidgets.cpp
@@ -16,8 +16,9 @@
#include <QDateTime>
#include <QShortcut>
#include "exif.h"
-#include "../dive.h"
-#include "../file.h"
+#include "dive.h"
+#include "file.h"
+#include "display.h"
#include "mainwindow.h"
#include "helpers.h"
@@ -117,15 +118,24 @@ RenumberDialog *RenumberDialog::instance()
return self;
}
+void RenumberDialog::renumberOnlySelected(bool selected)
+{
+ if (selected && amount_selected == 1)
+ ui.groupBox->setTitle(tr("New number"));
+ else
+ ui.groupBox->setTitle(tr("New starting number"));
+ selectedOnly = selected;
+}
+
void RenumberDialog::buttonClicked(QAbstractButton *button)
{
if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) {
qDebug() << "Renumbering.";
- renumber_dives(ui.spinBox->value());
+ renumber_dives(ui.spinBox->value(), selectedOnly);
}
}
-RenumberDialog::RenumberDialog(QWidget *parent) : QDialog(parent)
+RenumberDialog::RenumberDialog(QWidget *parent) : QDialog(parent), selectedOnly(false)
{
ui.setupUi(this);
connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
@@ -161,10 +171,10 @@ void ShiftTimesDialog::buttonClicked(QAbstractButton *button)
}
}
-void ShiftTimesDialog::showEvent(QShowEvent * event)
+void ShiftTimesDialog::showEvent(QShowEvent *event)
{
ui.timeEdit->setTime(QTime(0, 0, 0, 0));
- when = get_times();//get time of first selected dive
+ when = get_times(); //get time of first selected dive
ui.currentTime->setText(get_dive_date_string(when));
ui.shiftedTime->setText(get_dive_date_string(when));
}
@@ -177,7 +187,7 @@ void ShiftTimesDialog::changeTime()
if (ui.backwards->isChecked())
amount *= -1;
- ui.shiftedTime->setText (get_dive_date_string(amount+when));
+ ui.shiftedTime->setText(get_dive_date_string(amount + when));
}
ShiftTimesDialog::ShiftTimesDialog(QWidget *parent) : QDialog(parent)
diff --git a/qt-ui/simplewidgets.h b/qt-ui/simplewidgets.h
index d43d2bbcc..cecb52815 100644
--- a/qt-ui/simplewidgets.h
+++ b/qt-ui/simplewidgets.h
@@ -40,6 +40,7 @@ class RenumberDialog : public QDialog {
Q_OBJECT
public:
static RenumberDialog *instance();
+ void renumberOnlySelected(bool selected = true);
private
slots:
void buttonClicked(QAbstractButton *button);
@@ -47,17 +48,18 @@ slots:
private:
explicit RenumberDialog(QWidget *parent);
Ui::RenumberDialog ui;
+ bool selectedOnly;
};
class ShiftTimesDialog : public QDialog {
Q_OBJECT
public:
static ShiftTimesDialog *instance();
- void showEvent ( QShowEvent * event );
+ void showEvent(QShowEvent *event);
private
slots:
void buttonClicked(QAbstractButton *button);
- void changeTime ();
+ void changeTime();
private:
explicit ShiftTimesDialog(QWidget *parent);
diff --git a/qt-ui/subsurfacewebservices.cpp b/qt-ui/subsurfacewebservices.cpp
index 5170b3a40..c430deec6 100644
--- a/qt-ui/subsurfacewebservices.cpp
+++ b/qt-ui/subsurfacewebservices.cpp
@@ -49,7 +49,7 @@ static bool merge_locations_into_dives(void)
sort_table(&gps_location_table);
- for_each_gps_location(i, gpsfix) {
+ for_each_gps_location (i, gpsfix) {
if (is_automatic_fix(gpsfix)) {
dive = find_dive_including(gpsfix->when);
if (dive && !dive_has_gps_location(dive)) {
@@ -133,7 +133,9 @@ bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile,
}
/* walk the dive list in chronological order */
- for (int i = 0; i < dive_table.nr; i++) {
+ int i;
+ struct dive *dive;
+ for_each_dive (i, dive) {
FILE *f;
char filename[PATH_MAX];
int streamsize;
@@ -145,9 +147,6 @@ bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile,
* Get the i'th dive in XML format so we can process it.
* We need to save to a file before we can reload it back into memory...
*/
- struct dive *dive = get_dive(i);
- if (!dive)
- continue;
if (selected && !dive->selected)
continue;
f = tmpfile();
@@ -527,8 +526,8 @@ static DiveListResult parseDiveLogsDeDiveList(const QByteArray &xmlData)
if (reader.readNextStartElement() && reader.name() != "DiveDateReader") {
result.errorCondition = invalidXmlError;
result.errorDetails =
- DivelogsDeWebServices::tr("Expected XML tag 'DiveDateReader', got instead '%1")
- .arg(reader.name().toString());
+ DivelogsDeWebServices::tr("Expected XML tag 'DiveDateReader', got instead '%1")
+ .arg(reader.name().toString());
goto out;
}
@@ -581,8 +580,8 @@ out:
// if there was an XML error, overwrite the result or other error conditions
result.errorCondition = invalidXmlError;
result.errorDetails = DivelogsDeWebServices::tr("Malformed XML response. Line %1: %2")
- .arg(reader.lineNumber())
- .arg(reader.errorString());
+ .arg(reader.lineNumber())
+ .arg(reader.errorString());
}
return result;
}
@@ -602,11 +601,11 @@ void DivelogsDeWebServices::downloadDives()
exec();
}
-void DivelogsDeWebServices::prepareDivesForUpload()
+void DivelogsDeWebServices::prepareDivesForUpload(bool selected)
{
/* generate a random filename and create/open that file with zip_open */
QString filename = QDir::tempPath() + "/import-" + QString::number(qrand() % 99999999) + ".dld";
- if (prepare_dives_for_divelogs(filename, true)) {
+ if (prepare_dives_for_divelogs(filename, selected)) {
QFile f(filename);
if (f.open(QIODevice::ReadOnly)) {
uploadDives((QIODevice *)&f);
diff --git a/qt-ui/subsurfacewebservices.h b/qt-ui/subsurfacewebservices.h
index 4419b1c6b..a9a67de46 100644
--- a/qt-ui/subsurfacewebservices.h
+++ b/qt-ui/subsurfacewebservices.h
@@ -71,7 +71,7 @@ class DivelogsDeWebServices : public WebServices {
public:
static DivelogsDeWebServices *instance();
void downloadDives();
- void prepareDivesForUpload();
+ void prepareDivesForUpload(bool selected);
private
slots:
diff --git a/qt-ui/tagwidget.cpp b/qt-ui/tagwidget.cpp
index dfeeac537..8c45dceec 100644
--- a/qt-ui/tagwidget.cpp
+++ b/qt-ui/tagwidget.cpp
@@ -4,8 +4,9 @@
#include <QAbstractItemView>
#include <QSettings>
#include <QFont>
+#include "mainwindow.h"
-TagWidget::TagWidget(QWidget *parent) : GroupedLineEdit(parent), m_completer(NULL)
+TagWidget::TagWidget(QWidget *parent) : GroupedLineEdit(parent), m_completer(NULL), lastFinishedTag(false)
{
connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(reparse()));
connect(this, SIGNAL(textChanged()), this, SLOT(reparse()));
@@ -137,13 +138,13 @@ void TagWidget::reparse()
}
}
-void TagWidget::completionSelected(const QString& completion)
+void TagWidget::completionSelected(const QString &completion)
{
completionHighlighted(completion);
emit textChanged();
}
-void TagWidget::completionHighlighted(const QString& completion)
+void TagWidget::completionHighlighted(const QString &completion)
{
QPair<int, int> pos = getCursorTagPosition();
setText(text().remove(pos.first, pos.second - pos.first).insert(pos.first, completion));
@@ -157,7 +158,7 @@ void TagWidget::setCursorPosition(int position)
blockSignals(false);
}
-void TagWidget::setText(const QString& text)
+void TagWidget::setText(const QString &text)
{
blockSignals(true);
GroupedLineEdit::setText(text);
@@ -176,6 +177,7 @@ void TagWidget::keyPressEvent(QKeyEvent *e)
{
QPair<int, int> pos;
QAbstractItemView *popup;
+ bool finishedTag = false;
switch (e->key()) {
case Qt::Key_Escape:
pos = getCursorTagPosition();
@@ -183,7 +185,7 @@ void TagWidget::keyPressEvent(QKeyEvent *e)
setText(text().remove(pos.first, pos.second - pos.first));
setCursorPosition(pos.first);
}
- popup= m_completer->popup();
+ popup = m_completer->popup();
if (popup)
popup->hide();
return;
@@ -199,13 +201,17 @@ void TagWidget::keyPressEvent(QKeyEvent *e)
if (popup)
popup->hide();
}
+ finishedTag = true;
}
- if (e->key() == Qt::Key_Tab || e->key() == Qt::Key_Return) { // let's pretend this is a comma instead
+ if (e->key() == Qt::Key_Tab && lastFinishedTag) { // if we already end in comma, go to next/prev field
+ MainWindow::instance()->information()->nextInputField(e); // by sending the key event to the MainTab widget
+ } else if (e->key() == Qt::Key_Tab || e->key() == Qt::Key_Return) { // otherwise let's pretend this is a comma instead
QKeyEvent fakeEvent(e->type(), Qt::Key_Comma, e->modifiers(), QString(","));
GroupedLineEdit::keyPressEvent(&fakeEvent);
} else {
GroupedLineEdit::keyPressEvent(e);
}
+ lastFinishedTag = finishedTag;
}
void TagWidget::wheelEvent(QWheelEvent *event)
diff --git a/qt-ui/tagwidget.h b/qt-ui/tagwidget.h
index 62fa36f30..08984f712 100644
--- a/qt-ui/tagwidget.h
+++ b/qt-ui/tagwidget.h
@@ -12,21 +12,22 @@ public:
void setCompleter(QCompleter *completer);
QPair<int, int> getCursorTagPosition();
void highlight();
- void setText(const QString& text);
+ void setText(const QString &text);
void clear();
void setCursorPosition(int position);
void wheelEvent(QWheelEvent *event);
public
slots:
void reparse();
- void completionSelected(const QString& text);
- void completionHighlighted(const QString& text);
+ void completionSelected(const QString &text);
+ void completionHighlighted(const QString &text);
protected:
void keyPressEvent(QKeyEvent *e);
private:
QCompleter *m_completer;
+ bool lastFinishedTag;
};
#endif // TAGWIDGET_H
diff --git a/qt-ui/updatemanager.cpp b/qt-ui/updatemanager.cpp
index bcf58088d..75f454795 100644
--- a/qt-ui/updatemanager.cpp
+++ b/qt-ui/updatemanager.cpp
@@ -4,11 +4,10 @@
#include "subsurfacewebservices.h"
#include "ssrf-version.h"
-UpdateManager::UpdateManager(QObject *parent) :
- QObject(parent)
+UpdateManager::UpdateManager(QObject *parent) : QObject(parent)
{
manager = SubsurfaceWebServices::manager();
- connect (manager, SIGNAL(finished(QNetworkReply*)), SLOT(requestReceived(QNetworkReply*)));
+ connect(manager, SIGNAL(finished(QNetworkReply *)), SLOT(requestReceived(QNetworkReply *)));
}
void UpdateManager::checkForUpdates()
diff --git a/qt-ui/updatemanager.h b/qt-ui/updatemanager.h
index 18b47cfde..561c53d0b 100644
--- a/qt-ui/updatemanager.h
+++ b/qt-ui/updatemanager.h
@@ -6,16 +6,17 @@
class QNetworkAccessManager;
class QNetworkReply;
-class UpdateManager : public QObject
-{
+class UpdateManager : public QObject {
Q_OBJECT
public:
explicit UpdateManager(QObject *parent = 0);
void checkForUpdates();
+
private:
QNetworkAccessManager *manager;
-public slots:
- void requestReceived(QNetworkReply* reply);
+public
+slots:
+ void requestReceived(QNetworkReply *reply);
};
#endif // UPDATEMANAGER_H
diff --git a/qt-ui/usermanual.cpp b/qt-ui/usermanual.cpp
index 0dd39af33..60c94382f 100644
--- a/qt-ui/usermanual.cpp
+++ b/qt-ui/usermanual.cpp
@@ -11,9 +11,9 @@ UserManual::UserManual(QWidget *parent) : QMainWindow(parent),
{
ui->setupUi(this);
- QShortcut* closeKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this);
+ QShortcut *closeKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this);
connect(closeKey, SIGNAL(activated()), this, SLOT(close()));
- QShortcut* quitKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this);
+ QShortcut *quitKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this);
connect(quitKey, SIGNAL(activated()), parent, SLOT(close()));
QAction *actionShowSearch = new QAction(this);
diff --git a/qt-ui/usermanual.h b/qt-ui/usermanual.h
index 7692a1143..de8770eba 100644
--- a/qt-ui/usermanual.h
+++ b/qt-ui/usermanual.h
@@ -4,8 +4,7 @@
#include <QMainWindow>
#include <QWebPage>
-namespace Ui
-{
+namespace Ui {
class UserManual;
}
diff --git a/qthelper.cpp b/qthelper.cpp
index 101530dba..bcf78b5d1 100644
--- a/qthelper.cpp
+++ b/qthelper.cpp
@@ -6,12 +6,10 @@
#include <QDebug>
#include <QSettings>
#include <libxslt/documents.h>
-#include "mainwindow.h"
#define tr(_arg) QObject::tr(_arg)
-
QString weight_string(int weight_in_grams)
{
QString str;
@@ -88,39 +86,39 @@ bool parseGpsText(const QString &gps_text, double *latitude, double *longitude)
gpsStyle = ISO6709D;
regExp = QString("(\\d+)[" UTF8_DEGREE "\\s](\\d+)[\'\\s](\\d+)([,\\.](\\d+))?[\"\\s]([NS%1%2])"
"\\s*(\\d+)[" UTF8_DEGREE "\\s](\\d+)[\'\\s](\\d+)([,\\.](\\d+))?[\"\\s]([EW%3%4])")
- .arg(trHemisphere[0])
- .arg(trHemisphere[1])
- .arg(trHemisphere[2])
- .arg(trHemisphere[3]);
+ .arg(trHemisphere[0])
+ .arg(trHemisphere[1])
+ .arg(trHemisphere[2])
+ .arg(trHemisphere[3]);
} else if (gps_text.count(QChar('"')) == 2) {
gpsStyle = SECONDS;
regExp = QString("\\s*([NS%1%2])\\s*(\\d+)[" UTF8_DEGREE "\\s]+(\\d+)[\'\\s]+(\\d+)([,\\.](\\d+))?[^EW%3%4]*"
"([EW%5%6])\\s*(\\d+)[" UTF8_DEGREE "\\s]+(\\d+)[\'\\s]+(\\d+)([,\\.](\\d+))?")
- .arg(trHemisphere[0])
- .arg(trHemisphere[1])
- .arg(trHemisphere[2])
- .arg(trHemisphere[3])
- .arg(trHemisphere[2])
- .arg(trHemisphere[3]);
+ .arg(trHemisphere[0])
+ .arg(trHemisphere[1])
+ .arg(trHemisphere[2])
+ .arg(trHemisphere[3])
+ .arg(trHemisphere[2])
+ .arg(trHemisphere[3]);
} else if (gps_text.count(QChar('\'')) == 2) {
gpsStyle = MINUTES;
regExp = QString("\\s*([NS%1%2])\\s*(\\d+)[" UTF8_DEGREE "\\s]+(\\d+)([,\\.](\\d+))?[^EW%3%4]*"
"([EW%5%6])\\s*(\\d+)[" UTF8_DEGREE "\\s]+(\\d+)([,\\.](\\d+))?")
- .arg(trHemisphere[0])
- .arg(trHemisphere[1])
- .arg(trHemisphere[2])
- .arg(trHemisphere[3])
- .arg(trHemisphere[2])
- .arg(trHemisphere[3]);
+ .arg(trHemisphere[0])
+ .arg(trHemisphere[1])
+ .arg(trHemisphere[2])
+ .arg(trHemisphere[3])
+ .arg(trHemisphere[2])
+ .arg(trHemisphere[3]);
} else {
gpsStyle = DECIMAL;
regExp = QString("\\s*([-NS%1%2]?)\\s*(\\d+)[,\\.](\\d+)[^-EW%3%4\\d]*([-EW%5%6]?)\\s*(\\d+)[,\\.](\\d+)")
- .arg(trHemisphere[0])
- .arg(trHemisphere[1])
- .arg(trHemisphere[2])
- .arg(trHemisphere[3])
- .arg(trHemisphere[2])
- .arg(trHemisphere[3]);
+ .arg(trHemisphere[0])
+ .arg(trHemisphere[1])
+ .arg(trHemisphere[2])
+ .arg(trHemisphere[3])
+ .arg(trHemisphere[2])
+ .arg(trHemisphere[3]);
}
QRegExp r(regExp);
if (r.indexIn(gps_text) != -1) {
diff --git a/save-git.c b/save-git.c
index 3fd8807c6..6abba601a 100644
--- a/save-git.c
+++ b/save-git.c
@@ -845,14 +845,23 @@ static void create_commit_message(struct membuffer *msg)
if (dive) {
dive_trip_t *trip = dive->divetrip;
const char *location = dive->location ? : "no location";
+ struct divecomputer *dc = &dive->dc;
+ const char *sep = "\n";
if (dive->number)
nr = dive->number;
put_format(msg, "dive %d: %s", nr, location);
- if (trip->location && *trip->location && strcmp(trip->location, location))
+ if (trip && trip->location && *trip->location && strcmp(trip->location, location))
put_format(msg, " (%s)", trip->location);
- put_format(msg, "\n\n");
+ put_format(msg, "\n");
+ do {
+ if (dc->model && *dc->model) {
+ put_format(msg, "%s%s", sep, dc->model);
+ sep = ", ";
+ }
+ } while ((dc = dc->next) != NULL);
+ put_format(msg, "\n");
}
put_format(msg, "Created by subsurface %s\n", VERSION_STRING);
}
diff --git a/save-xml.c b/save-xml.c
index ddaa8cd2a..e52cfdffd 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -392,12 +392,8 @@ void save_one_dive(struct membuffer *b, struct dive *dive)
save_weightsystem_info(b, dive);
save_dive_temperature(b, dive);
/* Save the dive computer data */
- dc = &dive->dc;
- do {
+ for_each_dc(dive, dc)
save_dc(b, dive, dc);
- dc = dc->next;
- } while (dc);
-
put_format(b, "</dive>\n");
}
diff --git a/scripts/whitespace.pl b/scripts/whitespace.pl
index cc7c6511b..3131d22d4 100755
--- a/scripts/whitespace.pl
+++ b/scripts/whitespace.pl
@@ -3,17 +3,23 @@
my $input = $ARGV[0];
my $source = `clang-format $input`;
# for_each_dive (...) and Q_FOREACH and friends...
-$source =~ s/^(.*each.*\(.*\).*)\n\s*{\s*$/$1 {/img;
+$source =~ s/(?:\G|^)(.*each.*\(.*) \* (\S.*\))$/$1 *$2/img; # if a variable is declared in the argument, '*' is an indicator for a pointer, not arithmatic
+$source =~ s/(?:\G|^)(.*each.*\(.*) \& (\S.*\))$/$1 &$2/img; # if a variable is declared in the argument, '&' is an indicator for a reference, not bit logic
+$source =~ s/(?:\G|^)(.*each[^\s(]*)\s*(\(.*)$/$1 $2/img; # we want exactly one space between keyword and opening parenthesis '('
+$source =~ s/(?:\G|^)(.*each.*\(.*\).*)\n\s*{\s*$/$1 {/img; # we want the opening curly brace on the same line, separated by a space
$source =~ s/(?:\G|^)(\s+[^#\/*].*each.*\(.*\))\n(\s*)([^{}\s])/$1\n\t$2$3/img;
+# don't have '{' in the next line when declaring data types
$source =~ s/^(\s*struct[^()\n]*)\n\s*{\s*$/$1 {/img;
$source =~ s/^(\s*static\s+struct[^()\n]*)\n\s*{\s*$/$1 {/img;
$source =~ s/^(\s*union[^()\n]*)\n\s*{\s*$/$1 {/img;
$source =~ s/^(\s*static\s+union[^()\n]*)\n\s*{\s*$/$1 {/img;
$source =~ s/^(\s*class.*)\n\s*{\s*$/$1 {/img;
+# a namespace shouldn't look like a function
+$source =~ s/(?:\G|^)(namespace.*)\n{/$1 {/img;
# colon goes at the end of a line
$source =~ s/^(\S*::\S*.*)\n\s*: /$1 : /img;
-# odd indentations from flang-format:
+# odd indentations from clang-format:
# six spaces or four spaces after tabs (for continuation strings)
$source =~ s/(?:\G|^)[ ]{6}/\t/mg;
$source =~ s/(?:\G|^)(\t*)[ ]{4}"/$1\t"/mg;
@@ -23,15 +29,16 @@ $source =~ s/(?:\G|^)(\t*)[ ]{4}"/$1\t"/mg;
# from?
# I couldn't figure out how to make it apply to an arbitrary number of
# intermediate lines, so I hardcoded 0 through 5 lines between the #define
-# or #id defined statements and the end of the multi line statement
+# or #if defined statements and the end of the multi line statement
$source =~ s/^(#(?:if |)define.*)\n +([^*].*)$/$1\n\t$2/mg;
$source =~ s/^(#(?:if |)define.*)((?:\\\n.*){1})\n +([^*].*)$/$1$2\n\t$3/mg;
$source =~ s/^(#(?:if |)define.*)((?:\\\n.*){2})\n +([^*].*)$/$1$2\n\t$3/mg;
$source =~ s/^(#(?:if |)define.*)((?:\\\n.*){3})\n +([^*].*)$/$1$2\n\t$3/mg;
$source =~ s/^(#(?:if |)define.*)((?:\\\n.*){4})\n +([^*].*)$/$1$2\n\t$3/mg;
$source =~ s/^(#(?:if |)define.*)((?:\\\n.*){5})\n +([^*].*)$/$1$2\n\t$3/mg;
-# don't put line break before the last single term argument of a
-# calculation
+# don't put line break before the last single term argument of a calculation
$source =~ s/(?:\G|^)(.*[+-])\n\s*(\S*\;)$/$1 $2/mg;
-open (DIFF, "| diff -u $input -");
+$quotedinput = $input;
+$quotedinput =~ s|/|\\/|g;
+open (DIFF, "| diff -u $input - | sed -e 's/--- $quotedinput/--- $quotedinput.old/' | sed -e 's/+++ -/+++ $quotedinput/'");
print DIFF $source ;
diff --git a/statistics.c b/statistics.c
index 2a96efb81..71150159c 100644
--- a/statistics.c
+++ b/statistics.c
@@ -131,8 +131,7 @@ void process_all_dives(struct dive *dive, struct dive **prev_dive)
/* this relies on the fact that the dives in the dive_table
* are in chronological order */
- for (idx = 0; idx < dive_table.nr; idx++) {
- dp = dive_table.dives[idx];
+ for_each_dive (idx, dp) {
if (dive && dp->when == dive->when) {
/* that's the one we are showing */
if (idx > 0)
@@ -230,10 +229,10 @@ static void get_ranges(char *buffer, int size)
{
int i, len;
int first = -1, last = -1;
+ struct dive *dive;
snprintf(buffer, size, "%s", translate("gettextFromC", "for dives #"));
- for (i = 0; i < dive_table.nr; i++) {
- struct dive *dive = get_dive(i);
+ for_each_dive (i, dive) {
if (!dive->selected)
continue;
if (dive->number < 1) {
@@ -295,12 +294,12 @@ void get_selected_dives_text(char *buffer, int size)
static bool is_gas_used(struct dive *dive, int idx)
{
- struct divecomputer *dc = &dive->dc;
+ struct divecomputer *dc;
bool firstGasExplicit = false;
if (cylinder_none(&dive->cylinder[idx]))
return false;
- while (dc) {
+ for_each_dc(dive, dc) {
struct event *event = get_next_event(dc->events, "gaschange");
while (event) {
if (event->time.seconds < 30)
@@ -309,7 +308,6 @@ static bool is_gas_used(struct dive *dive, int idx)
return true;
event = get_next_event(event->next, "gaschange");
}
- dc = dc->next;
}
if (idx == 0 && !firstGasExplicit)
return true;
diff --git a/subsurface.pro b/subsurface.pro
index 7762318c5..83dea66a4 100644
--- a/subsurface.pro
+++ b/subsurface.pro
@@ -83,7 +83,8 @@ HEADERS = \
qt-ui/profile/diveeventitem.h \
qt-ui/profile/divetooltipitem.h \
qt-ui/profile/ruleritem.h \
- qt-ui/updatemanager.h
+ qt-ui/updatemanager.h \
+ qt-ui/divelogexportdialog.h
android: HEADERS -= \
qt-ui/usermanual.h \
@@ -157,7 +158,8 @@ SOURCES = \
qt-ui/profile/diveeventitem.cpp \
qt-ui/profile/divetooltipitem.cpp \
qt-ui/profile/ruleritem.cpp \
- qt-ui/updatemanager.cpp
+ qt-ui/updatemanager.cpp \
+ qt-ui/divelogexportdialog.cpp
android: SOURCES += android.cpp
else: linux*: SOURCES += linux.c
@@ -185,7 +187,8 @@ FORMS = \
qt-ui/webservices.ui \
qt-ui/tableview.ui \
qt-ui/divelogimportdialog.ui \
- qt-ui/usermanual.ui
+ qt-ui/usermanual.ui \
+ qt-ui/divelogexportdialog.ui
# Nether usermanual or printing is supported on android right now
android: FORMS -= qt-ui/usermanual.ui qt-ui/printoptions.ui
diff --git a/subsurfacestartup.c b/subsurfacestartup.c
index 471fea64e..4ae426d1c 100644
--- a/subsurfacestartup.c
+++ b/subsurfacestartup.c
@@ -149,13 +149,14 @@ void parse_argument(const char *arg)
} while (*++p);
}
-void renumber_dives(int nr)
+void renumber_dives(int start_nr, bool selected_only)
{
- int i;
+ int i, nr = start_nr;
+ struct dive *dive;
- for (i = 0; i < dive_table.nr; i++) {
- struct dive *dive = dive_table.dives[i];
- dive->number = nr + i;
+ for_each_dive (i, dive) {
+ if (dive->selected)
+ dive->number = nr++;
}
mark_divelist_changed(true);
}
diff --git a/uemis-downloader.c b/uemis-downloader.c
index d0c3de13e..5d8b07c01 100644
--- a/uemis-downloader.c
+++ b/uemis-downloader.c
@@ -793,14 +793,14 @@ static char *uemis_get_divenr(char *deviceidstr)
char divenr[10];
deviceid = atoi(deviceidstr);
- for (i = 0; i < dive_table.nr; i++) {
- struct divecomputer *dc = &dive_table.dives[i]->dc;
- while (dc) {
+ struct dive *d;
+ for_each_dive (i, d) {
+ struct divecomputer *dc;
+ for_each_dc(d, dc) {
if (dc->model && !strcmp(dc->model, "Uemis Zurich") &&
(dc->deviceid == 0 || dc->deviceid == 0x7fffffff || dc->deviceid == deviceid) &&
dc->diveid > maxdiveid)
maxdiveid = dc->diveid;
- dc = dc->next;
}
}
snprintf(divenr, 10, "%d", maxdiveid);
diff --git a/units.h b/units.h
index 0e168a21e..0a9e44b79 100644
--- a/units.h
+++ b/units.h
@@ -1,6 +1,8 @@
#ifndef UNITS_H
#define UNITS_H
+#include <math.h>
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/windows.c b/windows.c
index d2ba119ed..a8b7c55a6 100644
--- a/windows.c
+++ b/windows.c
@@ -36,56 +36,91 @@ const char *system_default_filename(void)
return buffer;
}
-int enumerate_devices(device_callback_t callback, void *userdata)
+int enumerate_devices(device_callback_t callback, void *userdata, int dc_type)
{
- // Open the registry key.
- HKEY hKey;
int index = -1;
- LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey);
- if (rc != ERROR_SUCCESS) {
- return -1;
- }
-
- // Get the number of values.
- DWORD count = 0;
- rc = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL);
- if (rc != ERROR_SUCCESS) {
- RegCloseKey(hKey);
- return -1;
- }
DWORD i;
- for (i = 0; i < count; ++i) {
- // Get the value name, data and type.
- char name[512], data[512];
- DWORD name_len = sizeof(name);
- DWORD data_len = sizeof(data);
- DWORD type = 0;
- rc = RegEnumValue(hKey, i, name, &name_len, NULL, &type, (LPBYTE)data, &data_len);
+ if (dc_type != DC_TYPE_UEMIS) {
+ // Open the registry key.
+ HKEY hKey;
+ LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey);
if (rc != ERROR_SUCCESS) {
- RegCloseKey(hKey);
return -1;
}
- // Ignore non-string values.
- if (type != REG_SZ)
- continue;
-
- // Prevent a possible buffer overflow.
- if (data_len >= sizeof(data)) {
+ // Get the number of values.
+ DWORD count = 0;
+ rc = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL);
+ if (rc != ERROR_SUCCESS) {
RegCloseKey(hKey);
return -1;
}
+ for (i = 0; i < count; ++i) {
+ // Get the value name, data and type.
+ char name[512], data[512];
+ DWORD name_len = sizeof(name);
+ DWORD data_len = sizeof(data);
+ DWORD type = 0;
+ rc = RegEnumValue(hKey, i, name, &name_len, NULL, &type, (LPBYTE)data, &data_len);
+ if (rc != ERROR_SUCCESS) {
+ RegCloseKey(hKey);
+ return -1;
+ }
- // Null terminate the string.
- data[data_len] = 0;
+ // Ignore non-string values.
+ if (type != REG_SZ)
+ continue;
- callback(data, userdata);
- index++;
- if (is_default_dive_computer_device(name))
- index = i;
+ // Prevent a possible buffer overflow.
+ if (data_len >= sizeof(data)) {
+ RegCloseKey(hKey);
+ return -1;
+ }
+
+ // Null terminate the string.
+ data[data_len] = 0;
+
+ callback(data, userdata);
+ index++;
+ if (is_default_dive_computer_device(name))
+ index = i;
+ }
+
+ RegCloseKey(hKey);
}
+ if (dc_type != DC_TYPE_SERIAL) {
+ int i;
+ int count_drives = 0;
+ const int bufdef = 512;
+ const char *dlabels[] = {"UEMISSDA", NULL};
+ char bufname[bufdef], bufval[bufdef], *p;
+ DWORD bufname_len;
+
+ /* add drive letters that match labels */
+ memset(bufname, 0, bufdef);
+ bufname_len = bufdef;
+ if (GetLogicalDriveStringsA(bufname_len, bufname)) {
+ p = bufname;
- RegCloseKey(hKey);
+ while (*p) {
+ memset(bufval, 0, bufdef);
+ if (GetVolumeInformationA(p, bufval, bufdef, NULL, NULL, NULL, NULL, 0)) {
+ for (i = 0; dlabels[i] != NULL; i++)
+ if (!strcmp(bufval, dlabels[i])) {
+ char data[512];
+ snprintf(data, sizeof(data), "%s (%s)", p, dlabels[i]);
+ callback(data, userdata);
+ if (is_default_dive_computer_device(p))
+ index = count_drives;
+ count_drives++;
+ }
+ }
+ p = &p[strlen(p) + 1];
+ }
+ if (count_drives == 1) /* we found exactly one Uemis "drive" */
+ index = 0; /* make it the selected "device" */
+ }
+ }
return index;
}
diff --git a/worldmap-options.h b/worldmap-options.h
index 6e7e8728b..177443563 100644
--- a/worldmap-options.h
+++ b/worldmap-options.h
@@ -1,7 +1,7 @@
#ifndef WORLDMAP_OPTIONS_H
#define WORLDMAP_OPTIONS_H
-const char* map_options = "center: new google.maps.LatLng(0,0),\n\tzoom: 3,\n\tminZoom: 2,\n\tmapTypeId: google.maps.MapTypeId.SATELLITE\n\t";
-const char* css = "\n\thtml { height: 100% }\n\tbody { height: 100%; margin: 0; padding: 0 }\n\t#map-canvas { height: 100% }\n";
+const char *map_options = "center: new google.maps.LatLng(0,0),\n\tzoom: 3,\n\tminZoom: 2,\n\tmapTypeId: google.maps.MapTypeId.SATELLITE\n\t";
+const char *css = "\n\thtml { height: 100% }\n\tbody { height: 100%; margin: 0; padding: 0 }\n\t#map-canvas { height: 100% }\n";
-#endif// WORLDMAP-OPTIONS_H
+#endif // WORLDMAP-OPTIONS_H
diff --git a/worldmap-save.c b/worldmap-save.c
index e867846f5..b82ccd3eb 100644
--- a/worldmap-save.c
+++ b/worldmap-save.c
@@ -6,6 +6,7 @@
#include "membuffer.h"
#include "worldmap-save.h"
#include "worldmap-options.h"
+#include "gettext.h"
char *getGoogleApi()
{
@@ -17,14 +18,20 @@ void put_HTML_date(struct membuffer *b, struct dive *dive)
{
struct tm tm;
utc_mkdate(dive->when, &tm);
- put_format(b, "<p>date=%04u-%02u-%02u</p>", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
- put_format(b, "<p>time=%02u:%02u:%02u</p>", tm.tm_hour, tm.tm_min, tm.tm_sec);
+ put_format(b, "<p>%s: %04u-%02u-%02u</p>", translate("gettextFromC", "Date"), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
+ put_format(b, "<p>%s: %02u:%02u:%02u</p>", translate("gettextFromC", "Time"), tm.tm_hour, tm.tm_min, tm.tm_sec);
}
void put_HTML_temp(struct membuffer *b, struct dive *dive)
{
- put_temperature(b, dive->airtemp, "<p>Air Temp: ", " C\\'</p>");
- put_temperature(b, dive->watertemp, "<p>Water Temp: ", " C\\'</p>");
+ const char *unit;
+ double value;
+
+ value = get_temp_units(dive->airtemp.mkelvin, &unit);
+ put_format(b, "<p>%s: %.1f %s</p>", translate("gettextFromC", "Air Temp"), value, unit);
+
+ value = get_temp_units(dive->watertemp.mkelvin, &unit);
+ put_format(b, "<p>%s: %.1f %s</p>", translate("gettextFromC", "Water Temp"), value, unit);
}
char *replace_char(char *str, char replace, char *replace_by)
@@ -78,27 +85,31 @@ void put_HTML_notes(struct membuffer *b, struct dive *dive)
{
if (dive->notes) {
char *notes = quote(dive->notes);
- put_format(b, "<p>Notes : %s </p>", notes);
+ put_format(b, "<p>%s: %s </p>", translate("gettextFromC", "Notes"), notes);
free(notes);
}
}
-void writeMarkers(struct membuffer *b)
+void writeMarkers(struct membuffer *b, const bool selected_only)
{
int i, dive_no = 0;
struct dive *dive;
for_each_dive(i, dive) {
- /*export selected dives only ?*/
-
+ if (selected_only) {
+ if (!dive->selected)
+ continue;
+ }
if (dive->latitude.udeg == 0 && dive->longitude.udeg == 0)
continue;
put_degrees(b, dive->latitude, "temp = new google.maps.Marker({position: new google.maps.LatLng(", "");
put_degrees(b, dive->longitude, ",", ")});\n");
put_string(b, "markers.push(temp);\ntempinfowindow = new google.maps.InfoWindow({content: '<div id=\"content\">'+'<div id=\"siteNotice\">'+'</div>'+'<div id=\"bodyContent\">");
+ put_format(b, "<p><b>%s</b></p>", quote(dive->location));
put_HTML_date(b, dive);
- put_duration(b, dive->duration, "<p>duration=", " min</p>");
+ put_duration(b, dive->duration, translate("gettextFromC", "<p>Duration: "), translate("gettextFromC", " min</p>"));
+ put_depth(b, dive->maxdepth, translate("gettextFromC", "<p>Max Depth: "), translate("gettextFromC", " m</p>"));
put_HTML_temp(b, dive);
put_HTML_notes(b, dive);
put_string(b, "</p>'+'</div>'+'</div>'});\ninfowindows.push(tempinfowindow);\n");
@@ -120,7 +131,7 @@ void insert_css(struct membuffer *b)
put_format(b, "<style type=\"text/css\">%s</style>\n", css);
}
-void insert_javascript(struct membuffer *b)
+void insert_javascript(struct membuffer *b, const bool selected_only)
{
put_string(b, "<script type=\"text/javascript\" src=\"");
put_string(b, getGoogleApi());
@@ -129,25 +140,25 @@ void insert_javascript(struct membuffer *b)
put_string(b, "rotateControl: false,\n\tstreetViewControl: false,\n\tmapTypeControl: false\n};\n");
put_string(b, "map = new google.maps.Map(document.getElementById(\"map-canvas\"),mapOptions);\nvar markers = new Array();");
put_string(b, "\nvar infowindows = new Array();\nvar temp;\nvar tempinfowindow;\n");
- writeMarkers(b);
+ writeMarkers(b, selected_only);
put_string(b, "\nfor(var i=0;i<markers.length;i++)\n\tmarkers[i].setMap(map);\n}\n");
put_string(b, "google.maps.event.addDomListener(window, 'load', initialize);</script>\n");
}
-void export(struct membuffer *b)
+void export(struct membuffer *b, const bool selected_only)
{
insert_html_header(b);
insert_css(b);
- insert_javascript(b);
+ insert_javascript(b, selected_only);
put_string(b, "\t</head>\n<body>\n<div id=\"map-canvas\"></div>\n</body>\n</html>");
}
-void export_worldmap_HTML(const char *file_name)
+void export_worldmap_HTML(const char *file_name, const bool selected_only)
{
FILE *f;
struct membuffer buf = { 0 };
- export(&buf);
+ export(&buf, selected_only);
f = fopen(file_name, "w+");
if (!f)
diff --git a/worldmap-save.h b/worldmap-save.h
index 72363e482..102ea40e5 100644
--- a/worldmap-save.h
+++ b/worldmap-save.h
@@ -5,7 +5,7 @@
extern "C" {
#endif
-extern void export_worldmap_HTML(const char* x);
+extern void export_worldmap_HTML(const char *file_name, const bool selected_only);
#ifdef __cplusplus