source: subversion/applications/editors/osm-editor/qt3/MainWindow2.cpp @ 16590

Last change on this file since 16590 was 1158, checked in by nick, 13 years ago

moved current version to qt3 directory in preparation for qt4

File size: 59.8 KB
Line 
1/*
2    Copyright (C) 2005 Nick Whitelegg, Hogweed Software, nick@hogweed.org
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
17
18 */
19
20// 180306 started way provision (multiple selected segments)
21// 180306 changed 0.2 API calls to 0.3; renamed newnode and newsegment to
22// node/0 and segment/0.
23
24#include "MainWindow2.h"
25#include "functions.h"
26#include "SRTMConGen.h"
27
28#include <iostream>
29#include <sstream>
30#include <cstdlib>
31#include <cmath>
32
33#include <qapplication.h>
34#include <qpainter.h>
35#include <qfontmetrics.h>
36#include <qpopupmenu.h>
37#include <qmenubar.h>
38#include <qfiledialog.h>
39#include <qmessagebox.h>
40#include <qinputdialog.h>
41#include <qtoolbar.h>
42#include <qlabel.h>
43#include <qsignalmapper.h>
44#include <qtextstream.h>
45#include <qcstring.h>
46
47#include "WaypointDialogue.h"
48#include "WayDialogue.h"
49#include "LoginDialogue.h"
50
51#include <qxml.h>
52#include "OSMParser2.h"
53#include "GPXParser2.h"
54
55#include "qmdcodec.h"
56
57#include <cmath>
58
59#ifdef XMLRPC
60#include <string>
61#include <XmlRpcCpp.h>
62#endif
63
64
65using std::cout;
66using std::endl;
67using std::cerr;
68
69namespace OpenStreetMap
70{
71
72QPixmap mmLoadPixmap(const QString& directory, const QString& filename) ;
73
74void WaypointRep::draw(QPainter & p,int x,int y, const QString& label)
75{
76    QString lbl = label; // to get round lack of const in QTextStream
77    if(!image.isNull())
78    {
79        p.drawPixmap(x-image.width()/2,y-image.height()/2,image);
80    }
81
82    // Only attempt to draw supplied label if this image type expects one
83    if(labelData)
84    {
85        QFontMetrics fm(labelData->font);
86        int labelY = (image.isNull() ? y:y + image.height()/2),
87            labelX = (image.isNull() ? x:x + image.width()/2);
88
89        p.setPen(labelData->colour);
90        p.setFont(labelData->font);
91
92        // Draw feature label one word per line
93        QTextStream strm(&lbl,IO_ReadOnly);
94        QString word;
95        while(!strm.atEnd())
96        {
97            strm>>word;
98            p.drawText(labelX,labelY,word);
99            labelY += fm.height();
100        }
101    }
102}
103
104MainWindow2::MainWindow2(double lat,double lon, double s,double w,double h) :
105                                    map(lon,lat,s,w,h),
106                                    landsatManager(this,w,h,100),
107                                    osmhttp("www.openstreetmap.org"),
108                                                                        tpPixmap("images/trackpoint.png")
109{
110    cerr<<"constructor"<<endl;
111    setCaption("OpenStreetMap Editor");
112    resize ( w, h );       
113
114    LIMIT=map.earthDist(10);
115
116    newUploadedNode =NULL;
117    newUploadedSegment = NULL;
118
119    contours = false;
120    wptSaved = false;
121        displayOSM = true;
122        displayGPX = true;
123        showSegmentColours = false;
124
125    actionMode = ACTION_NODE;
126    curSegType = "track";
127    nSelectedPoints = 0;
128    nSelectedTrackPoints = 0;
129        tpts[0] = tpts[1] = -1;
130
131    doingName = false;
132
133        // change these to match the renderer
134       
135    segpens["footpath"]= SegPen (QPen (Qt::green, 2), false );
136    segpens["path"]= SegPen (QPen (QColor(0,192,0), 2), false);
137    segpens["cycle path"]= SegPen(QPen (Qt::magenta, 2), false);
138    segpens["bridleway"]= SegPen (QPen(QColor(192,96,0),2), false);
139    segpens["byway"] = SegPen (QPen (Qt::red, 2), false);
140    segpens["minor road"]= SegPen (QPen(QColor(192,192,192), 2),true);
141    segpens["residential road"]= SegPen(QPen (QColor(192,192,192), 1), true);
142    segpens["B road"]= SegPen(QPen (QColor(253,191,111), 4), true);
143    segpens["A road"]= SegPen(QPen (QColor(251,128,95), 4), true);
144    segpens["motorway"]= SegPen(QPen (QColor(128,155,192), 4), true);
145    segpens["railway"]= SegPen(QPen (Qt::black, 2), false);
146    segpens["permissive footpath"]= SegPen(QPen (QColor(0,192,0), 2), false);
147    segpens["permissive bridleway"]= SegPen(QPen (QColor(170,85,0), 2), false);
148    segpens["track"]= SegPen(QPen (QColor(128,128,128), 3), false);
149    segpens["new forest track"]=SegPen(QPen(QColor(170,85,0),2), false);
150    segpens["new forest cycle path"]= SegPen(QPen (Qt::magenta, 2), false);
151    cerr<<"done segpens" << endl;
152
153    areapens["wood"]= QPen (QColor(192,255,192));
154    areapens["heath"]= QPen (QColor(255,255,192));
155    areapens["lake"]= QPen (QColor(0,0,128));
156
157    // Construct the menus.
158    QPopupMenu* fileMenu = new QPopupMenu(this);
159    // 29/10/05 Only open "OSM" now
160    fileMenu->insertItem("&Open",this,SLOT(open()),CTRL+Key_O);
161    fileMenu->insertItem("&Save",this,SLOT(save()),CTRL+Key_S);
162    fileMenu->insertItem("Save &as...",this,SLOT(saveAs()),CTRL+Key_A);
163    fileMenu->insertItem("Save GPX...",this,SLOT(saveGPX()),CTRL+Key_X);
164    fileMenu->insertItem("&Read GPS",this,SLOT(readGPS()),CTRL+Key_R);
165    fileMenu->insertItem("&Grab Landsat",this,SLOT(grabLandsat()),CTRL+Key_G);
166    fileMenu->insertItem("Grab OSM from &Net",this,SLOT(grabOSMFromNet()),
167                                CTRL+Key_N);
168    fileMenu->insertItem("Grab OSM GPX tracks",this,SLOT(grabGPXFromNet()));
169    fileMenu->insertItem("&Upload OSM",this,SLOT(uploadOSM()),CTRL+Key_U);
170    fileMenu->insertItem("&Quit", this, SLOT(quit()), ALT+Key_Q);
171    fileMenu->insertItem("Login to live update",this,
172                        SLOT(loginToLiveUpdate()));
173    fileMenu->insertItem("Logout from live update",this,
174                        SLOT(logoutFromLiveUpdate()));
175        fileMenu->insertItem("Upload waypoints",this, SLOT(uploadNewWaypoints()));
176        fileMenu->insertItem("Batch upload",this, SLOT(batchUpload()));
177    menuBar()->insertItem("&File",fileMenu);
178    QPopupMenu* editMenu = new QPopupMenu(this);
179   
180    editMenu->insertItem("&Toggle nodes",this,SLOT(toggleNodes()),
181                        CTRL+Key_T);
182    editMenu->insertItem("Toggle &Landsat",this,SLOT(toggleLandsat()),
183                        CTRL+Key_L);
184    editMenu->insertItem("Toggle &contours",this,SLOT(toggleContours()),
185                        CTRL+Key_C);
186    editMenu->insertItem("Toggle segment colours",this,
187                                        SLOT(toggleSegmentColours()));
188    editMenu->insertItem("Remove trac&k points",this,SLOT(removeTrackPoints()),
189                        CTRL+Key_K);
190        editMenu->insertItem("Change serial port", this, SLOT(changeSerialPort()));
191//      editMenu->insertItem("Undo",this,SLOT(undo()),CTRL+Key_Z);
192    menuBar()->insertItem("&Edit",editMenu);
193
194    QToolBar* toolbar=new QToolBar(this);
195    toolbar->setHorizontalStretchable(true);
196
197        /* 050706 remove - now all way attribute editing via dialog box
198    new QLabel("Way type: ", toolbar);
199    QComboBox* r = new QComboBox(toolbar);
200    for(std::map<QString,SegPen>::iterator i=segpens.begin(); i!=segpens.end();
201        i++)
202    {
203        r->insertItem(i->first);
204    }
205        r->setCurrentText("track");
206
207    QObject::connect(r,SIGNAL(activated(const QString&)),
208                        this,SLOT(setSegType(const QString&)));
209                                                */
210
211    cerr<<"done combo box" << endl;
212    // Do the toolbar buttons to change the mode.
213    //
214    // Construct a signal mapper so that each mode button can be mapped to
215    // one slot (i.e. setMode()). The setMapping() method of the signal
216    // mapper enables you to hook up a particular value to each button,
217    // enabling a range of buttons representing values to be mapped to one
218    // slot which takes an int.
219   
220
221    QSignalMapper* mapper = new QSignalMapper(this);
222
223
224    QPixmap one = mmLoadPixmap("images","one.png");
225    QPixmap two = mmLoadPixmap("images","two.png");
226    QPixmap deleteseg = mmLoadPixmap("images","deleteseg.png");
227    QPixmap wp = mmLoadPixmap("images","waypoint.png");
228    QPixmap three = mmLoadPixmap("images","three.png");
229    QPixmap nametracks = mmLoadPixmap("images","nametracks.png");
230    QPixmap objectmanip = mmLoadPixmap("images","objectmanip.png");
231    QPixmap linknewpoint = mmLoadPixmap("images","linknewpoint.png");
232    QPixmap formnewseg = mmLoadPixmap("images","formnewseg.png");
233    QPixmap breakseg = mmLoadPixmap("images","breakseg.png");
234    QPixmap seltrk = mmLoadPixmap("images","seltrk.png");
235    QPixmap ways = mmLoadPixmap("images","ways.png");
236    QPixmap uploadways = mmLoadPixmap("images","uploadways.png");
237    QPixmap waydelete = mmLoadPixmap("images","waydelete.png");
238    QPixmap left_pixmap = mmLoadPixmap("images","arrow_left.png");
239    QPixmap right_pixmap = mmLoadPixmap("images","arrow_right.png");
240    QPixmap up_pixmap = mmLoadPixmap("images","arrow_up.png");
241    QPixmap down_pixmap = mmLoadPixmap("images","arrow_down.png");
242    QPixmap magnify_pixmap = mmLoadPixmap("images","magnify.png");
243    QPixmap shrink_pixmap = mmLoadPixmap("images","shrink.png");
244    QPixmap selseg_pixmap = mmLoadPixmap("images","selseg.png");
245    QPixmap selway_pixmap = mmLoadPixmap("images","selway.png");
246    QPixmap osm = mmLoadPixmap("images","osm.png");
247    QPixmap gpx = mmLoadPixmap("images","gpx.png");
248    QPixmap landsat = mmLoadPixmap("images","landsat.png");
249    QPixmap contours = mmLoadPixmap("images","contours.png");
250    QPixmap segcol = mmLoadPixmap("images","segcol.png");
251    QPixmap editway = mmLoadPixmap("images","editway.png");
252
253    new QToolButton(left_pixmap,"Move left","",this,SLOT(left()),toolbar);
254    new QToolButton(right_pixmap,"Move right","",this,SLOT(right()),toolbar);
255    new QToolButton(up_pixmap,"Move up","",this,SLOT(up()),toolbar);
256    new QToolButton(down_pixmap,"Move down","",this,SLOT(down()),toolbar);
257    new QToolButton(magnify_pixmap,"Zoom in","",this,SLOT(magnify()),toolbar);
258    new QToolButton(shrink_pixmap,"Zoom out","",this,SLOT(shrink()),toolbar);
259
260    QToolBar  *toolbar2 = new QToolBar(this);
261    toolbar2->setHorizontalStretchable(true);
262//      moveDockWindow (toolbar2,Qt::DockLeft);
263
264
265   
266    modeButtons[ACTION_NODE]= new QToolButton
267            (wp,"Edit Nodes","",mapper,SLOT(map()),toolbar2);
268    modeButtons[ACTION_MOVE_NODE]= new QToolButton
269            (objectmanip,"Move Node","",mapper,SLOT(map()),toolbar2);
270    modeButtons[ACTION_DELETE_NODE]= new QToolButton
271            (two,"Delete Node","",mapper,SLOT(map()),toolbar2);
272    modeButtons[ACTION_SEL_SEG]= new QToolButton
273            (selseg_pixmap,"Select segment","",mapper,SLOT(map()),toolbar2);
274    modeButtons[ACTION_SEL_WAY]= new QToolButton
275            (selway_pixmap,"Select way","",mapper,SLOT(map()),toolbar2);
276    modeButtons[ACTION_NEW_SEG]= new QToolButton
277            (formnewseg,"New segment","",mapper,SLOT(map()),toolbar2);
278    modeButtons[ACTION_BREAK_SEG]= new QToolButton
279            (breakseg,"Break segment","",mapper,SLOT(map()),toolbar2);
280    modeButtons[ACTION_SEL_TRACK]= new QToolButton
281            (seltrk,"Select section of track","",mapper,SLOT(map()),toolbar2);
282    new QToolButton
283            (deleteseg,"Delete Selected Segment/Way/GPX Track","",this,
284             SLOT(deleteSelectedSeg()),toolbar);
285    wayButton = new QToolButton
286            (ways,"Way construction on/off","",this,
287             SLOT(toggleWays()),toolbar);
288        wayButton->setToggleButton(true);
289        wayButton->setOn(false);
290
291    new QToolButton
292            (uploadways,"Upload current way","",this,
293             SLOT(uploadWay()),toolbar);
294       
295       
296    new QToolButton
297            (editway,"Way Details/Edit Way","",this,
298             SLOT(changeWayDetails()),toolbar);
299
300                       
301    osmButton = new QToolButton
302            (osm,"OSM Data On/Off","",this,
303             SLOT(toggleOSM()),toolbar);
304        osmButton->setToggleButton(true);
305        osmButton->setOn(true);
306
307    gpxButton = new QToolButton
308            (gpx,"OSM GPX Tracks On/Off","",this,
309             SLOT(toggleGPX()),toolbar);
310        gpxButton->setToggleButton(true);
311        gpxButton->setOn(true);
312
313    landsatButton = new QToolButton
314            (landsat,"Landsat On/Off","",this,
315             SLOT(toggleLandsat()),toolbar);
316        landsatButton->setToggleButton(true);
317        landsatButton->setOn(false);
318
319    contoursButton = new QToolButton
320            (contours,"SRTM Contours On/Off","",this,
321             SLOT(toggleContours()),toolbar);
322        contoursButton->setToggleButton(true);
323        contoursButton->setOn(false);
324   
325    showSegmentColoursButton = new QToolButton
326            (segcol,"Segment Type Indication On/Off","",this,
327             SLOT(toggleSegmentColours()),toolbar);
328        showSegmentColoursButton->setToggleButton(true);
329        showSegmentColoursButton->setOn(false);
330
331    toolbar->setStretchableWidget(new QLabel(toolbar));
332    toolbar2->setStretchableWidget(new QLabel(toolbar2));
333
334    // Setting a blank label as the stretchable widget means that one can
335    // stretch the toolbar while keeping the tool buttons bunched up to the
336    // left.
337
338    // Turn the "mode" toolbar buttons into toggle buttons, and set their
339    // mapping index for the signal mapper.
340   
341   
342    for (int count=0; count<N_ACTIONS; count++)
343    {
344        modeButtons[count]->setToggleButton(true);
345        mapper->setMapping(modeButtons[count],count);
346    }
347   
348    modeButtons[ACTION_NODE]->setOn(true);
349   
350
351    // The final stage of implementing the signal mapper: connect mapped()
352    // to setMode(). The value set in setMapping() above will be used.
353    QObject::connect(mapper,SIGNAL(mapped(int)),this,SLOT(setMode(int)));
354
355
356    nodeReps["pub"] = new WaypointRep
357            ("images/pub.png","Helvetica",10, QColor(170,85,0));
358    nodeReps["church"] = new WaypointRep ( "images/church.png");
359    nodeReps["viewpoint"] = new WaypointRep("images/viewpoint.png");
360    nodeReps["farm"] = new WaypointRep("images/farm.png",
361                    "Helvetica",8,Qt::red);
362    nodeReps["hill"] = new WaypointRep(
363                    "images/peak.png","Helvetica",10, Qt::magenta);
364    nodeReps["hamlet"] = new WaypointRep(
365                    "images/place.png","Helvetica",12, Qt::black);
366    nodeReps["village"] = new WaypointRep(
367                    "images/place.png","Helvetica",16, Qt::black);
368    nodeReps["small town"] = new WaypointRep(
369                    "images/place.png","Helvetica",20, Qt::black);
370    nodeReps["large town"] = new WaypointRep(
371                    "images/place.png","Helvetica",24, Qt::black);
372    nodeReps["car park"] = new WaypointRep(
373                    "images/carpark.png", "Helvetica",8,Qt::blue);
374    nodeReps["railway station"] = new WaypointRep(
375                    "images/station.png", "Helvetica",10,Qt::red);
376    nodeReps["mast"] = new WaypointRep(
377                    "images/mast.png");
378    nodeReps["point of interest"] = new WaypointRep
379            ("images/interest.png");
380    nodeReps["suburb"] = new WaypointRep(
381            "images/place.png","Helvetica",16, Qt::black);
382    nodeReps["trackpoint"] = new WaypointRep(
383                    "images/trackpoint.png","Helvetica",8,Qt::black);
384    nodeReps["node"] = new WaypointRep(
385                    "images/node.png","Helvetica",8,Qt::black);
386    nodeReps["waypoint"] = new WaypointRep(
387                    "images/waypoint.png","Helvetica",8,Qt::black);
388
389    nodeReps["campsite"] = new WaypointRep(
390                    "images/campsite.png","Helvetica",8,QColor(0,128,0));
391    nodeReps["restaurant"] = new WaypointRep(
392                    "images/restaurant.png","Helvetica",8,QColor(128,0,0));
393    nodeReps["bridge"] = new WaypointRep("images/bridge.png");
394    nodeReps["tea shop"] = new WaypointRep(
395                    "images/teashop.png","Helvetica",8,Qt::magenta);
396    nodeReps["country park"] = new WaypointRep("images/park.png",
397                            "Helvetica",8,QColor(0,192,0));
398    nodeReps["industrial area"] = new WaypointRep("images/industry.png",
399                            "Helvetica",8,Qt::darkGray);
400    nodeReps["barn"] = new WaypointRep("images/barn.png");
401    curFilename = "";
402
403    trackpoints=true;
404
405    components = new Components2;
406    osmtracks = new Components2;
407
408        clearSegments();
409
410    setFocusPolicy(QWidget::ClickFocus);
411
412    showPosition();
413
414    username = "";
415    password = "";
416
417    liveUpdate = false;
418
419    cerr<<"end constructor"<<endl;
420    movingNode = NULL;     
421
422        makingWay = false;
423
424    QObject::connect(&osmhttp,SIGNAL(httpErrorOccurred(int,const QString&)),
425                    this,SLOT(handleHttpError(int,const QString&)));
426    QObject::connect(&osmhttp,SIGNAL(errorOccurred(const QString&)),
427                    this,SLOT(handleNetCommError(const QString&)));
428
429        serialPort = "/dev/ttyS0";
430
431        selWay = NULL;
432        splitter = NULL;
433
434        uploader = NULL;
435}
436
437MainWindow2::~MainWindow2()
438{
439    for (std::map<QString,WaypointRep*>::iterator i=nodeReps.begin();
440         i!=nodeReps.end(); i++)
441    {
442        delete i->second;
443    }
444
445    components->destroy();
446    delete components;
447}
448
449void MainWindow2::open()
450{
451    QFileDialog* fd = new QFileDialog( this,"openbox",true );
452    fd->setViewMode( QFileDialog::List );
453    fd->setCaption(tr("Open osm or gpx...")); 
454    fd->setFilter("GPS Exchange (*.gpx)");
455    fd->addFilter("Openstreetmap data (*.osm)");
456    fd->setMode( QFileDialog::ExistingFile );
457
458    QString filename;
459    if ( fd->exec() != QDialog::Accepted )
460    {   delete fd;
461        return;
462    }
463    filename = fd->selectedFile();
464    if (filename.isEmpty())
465    {   delete fd;
466        return;
467    }
468    if (fd->selectedFilter().contains("osm"))
469    {  // OSM DATA
470        Components2 *newComponents = doOpen(filename);
471        if(newComponents)
472        {
473            try
474            {
475                map.centreAt(newComponents->getAveragePoint());
476                if(components)
477                {
478                    components->merge(newComponents);
479                    delete newComponents;
480                }
481                else
482                {
483                    components = newComponents;
484                }
485                curFilename = filename;
486                showPosition();
487                update();
488            }
489            catch(QString str)
490            {
491                // blank track, trackseg etc
492            }
493        }
494    }
495    else   
496    {   // GPX Data
497        Components2 * comp;
498                GPXParser2 parser;
499        cerr<<"filename=" << filename<<endl;
500        QFile file(filename);
501        QXmlInputSource source(&file);
502        QXmlSimpleReader reader;
503        reader.setContentHandler(&parser);
504        reader.parse(source);
505        comp = parser.getComponents(); 
506                map.centreAt(comp->getAverageTrackPoint());
507                if(components)
508                {
509                        components->merge(comp);
510                        delete comp;
511                }
512                else
513                {
514                        components = comp;
515                }
516                showPosition();
517                update();
518    }
519    /* Delete fd; ? */
520        delete fd;
521}
522
523Components2 * MainWindow2::doOpen(const QString& filename)
524{
525    cerr<<"doOpen"<<endl;
526    Components2 * comp;
527
528   
529    OSMParser2 parser;
530    cerr<<"filename=" << filename<<endl;
531    QFile file(filename);
532    QXmlInputSource source(&file);
533    QXmlSimpleReader reader;
534    reader.setContentHandler(&parser);
535    reader.parse(source);
536    comp = parser.getComponents(); 
537    return comp;
538   
539}
540
541void MainWindow2::loginToLiveUpdate()
542{
543    QString str = "WARNING!!! The login and password you supply will be\n"\
544                  "stored in osm-editor's memory and sent to the server\n"\
545                  "each time you perform a live update action.\n"\
546                  "This will happen until\n"\
547                "you select Logout or exit osm-editor. If you\n "\
548                "leave the computer, someone else will be able to modify\n "\
549                "OSM data!!! Press Cancel next if you're unhappy!";
550//    QMessageBox::warning(this,"Warning!",str);
551    LoginDialogue *ld=new LoginDialogue(this);
552    if(ld->exec())
553    {
554        username = ld->getUsername();
555        password = ld->getPassword();
556        liveUpdate = true;
557        showPosition();
558    }
559    delete ld;
560}
561
562void MainWindow2::logoutFromLiveUpdate()
563{
564    username = "";
565    password = "";
566    liveUpdate = false;
567    showPosition();
568}
569
570void MainWindow2::grabOSMFromNet()
571{
572    QString url="http://www.openstreetmap.org/api/0.3/map";
573    QString uname="", pwd="";
574    Components2 * netComponents;
575    statusBar()->message("Grabbing data from OSM...");
576    EarthPoint bottomLeft = map.getBottomLeft(),
577               topRight = map.getTopRight();
578    if(username=="" || password=="")
579    {
580        LoginDialogue *ld=new LoginDialogue(this);
581        if(ld->exec())
582        {
583            uname=ld->getUsername(),
584            pwd=ld->getPassword();
585        }
586        delete ld;
587    }
588    else
589    {
590        uname=username;
591        pwd = password;
592    }
593
594    if(uname!="" && pwd!="")
595    {
596        statusBar()->message("Grabbing data from OSM...");
597        EarthPoint bottomLeft = map.getBottomLeft(),
598               topRight = map.getTopRight();
599        QString url;
600        url.sprintf("/api/0.3/map?bbox=%lf,%lf,%lf,%lf",
601                            bottomLeft.x,bottomLeft.y,
602                            topRight.x,topRight.y);
603        cerr<<"SENDING URL: "<<url<<endl;
604
605                osmhttp.setAuthentication(uname,pwd);
606                osmhttp.scheduleCommand("GET",url,QByteArray(),
607                                                                this,
608                                                                SLOT(loadComponents(const QByteArray&,void*)));
609    }
610}
611
612void MainWindow2::grabGPXFromNet()
613{
614    QString url;
615    QString uname="", pwd="";
616    EarthPoint bottomLeft = map.getBottomLeft(), topRight = map.getTopRight();
617    if(username=="" || password=="")
618    {
619        LoginDialogue *ld=new LoginDialogue(this);
620        if(ld->exec())
621        {
622            uname=ld->getUsername(),
623            pwd=ld->getPassword();
624        }
625        delete ld;
626    }
627    else
628    {
629        uname=username;
630        pwd = password;
631    }
632
633    if(uname!="" && pwd!="")
634    {
635        statusBar()->message("Grabbing tracks from OSM...");
636        EarthPoint bottomLeft = map.getBottomLeft(),
637               topRight = map.getTopRight();
638        QString url;
639        url.sprintf("/api/0.3/trackpoints?bbox=%lf,%lf,%lf,%lf&page=0",
640                            bottomLeft.x,bottomLeft.y,
641                            topRight.x,topRight.y);
642        cerr<<"SENDING URL: "<<url<<endl;
643
644                osmhttp.setAuthentication(uname,pwd);
645                osmhttp.scheduleCommand("GET",url,QByteArray(),
646                                                                this,
647                                                                SLOT(loadOSMTracks(const QByteArray&,void*)));
648    }
649}
650
651void MainWindow2::loadComponents(const QByteArray& array,void*)
652{
653        //QMessageBox::information(this,"Received data", "Data has been received.");
654        cerr << "loadComponents()" << endl;
655        cerr << "array:" << array << endl;
656
657    Components2 *netComponents;
658
659    QXmlInputSource source;
660    source.setData(array);
661
662    OSMParser2 parser;
663    QXmlSimpleReader reader;
664    reader.setContentHandler(&parser);
665    reader.parse(source);
666    netComponents = parser.getComponents();
667
668    if(components)
669    {
670        components->merge(netComponents);
671        delete netComponents;
672    }
673    else
674    {
675        components = netComponents;
676    }
677        showPosition();
678    update();
679}
680
681
682// 240306 hacky upload stuff removed as batch upload of nodes no longer
683// appears to be supported by the server.
684void MainWindow2::uploadOSM()
685{
686        QMessageBox::information(this,
687                        "Batch OSM upload temporarily unavailable",
688                        "Batch OSM upload temporarily unavailable"); 
689}
690
691
692void MainWindow2::readGPS()
693{
694    try
695    {
696        GPSDevice2 device ("Garmin", serialPort);
697        Components2 *c = device.getSurveyedComponents();
698        if(c)
699        {
700            map.centreAt(c->getAveragePoint());     
701            cerr << "GPS read done. " << std::endl;
702            if(components)
703            {
704                components->merge(c);
705                delete c;
706            }
707            else
708            {
709                components = c;
710            }
711            showPosition();
712            update();
713        }
714    }
715    catch(QString str)
716    {
717        cerr<<str<<endl;
718    }
719}
720
721void MainWindow2::save()
722{
723    if(curFilename == "")
724        saveAs();
725    else
726        saveFile(curFilename);
727}
728
729void MainWindow2::saveAs()
730{
731    QString filename = QFileDialog::getSaveFileName("","*.osm",this);
732    if(filename!="")
733        saveFile(filename);
734}
735
736void MainWindow2::saveFile(const QString& filename)
737{
738//      components->toGPX(filename);   
739    curFilename = filename;
740    QFile file (filename);
741    if(file.open(IO_WriteOnly))
742    {
743        QTextStream strm(&file);
744        components->toOSM(strm,true);
745        file.close();
746    }
747}
748
749void MainWindow2::saveGPX()
750{
751    QString filename = QFileDialog::getSaveFileName("","*.gpx",this);
752    QFile file (filename);
753    if(file.open(IO_WriteOnly))
754    {
755        QTextStream strm(&file);
756        components->toGPX(strm);
757        file.close();
758    }
759}
760void MainWindow2::quit()
761{
762    QApplication::exit(0);
763}
764
765void MainWindow2::setMode(int m)
766{
767    actionMode=  m;
768
769    // Display the appropriate mode toolbar button and menu item checked, and
770    // all the others turned off.
771    for (int count=0; count<N_ACTIONS; count++)
772        modeButtons[count]->setOn(count==m);
773
774    // Wipe any currently selected points
775    nSelectedPoints = 0;
776
777        if(m!=ACTION_BREAK_SEG)
778        {
779                cerr<<"setMode(): CLEARING SEGMENTS" << endl;
780                clearSegments();
781        }       
782
783    movingNode = NULL;
784    pts[0]=pts[1]=NULL;
785    doingName = false;
786    update();
787}
788
789/* 050706 all this goes (all done via dialog; also can't change a segment
790 * type anymore. YOU *WILL* USE WAYS, WHETHER YOU LIKE IT OR NOT!!!! AND
791 * THAT'S AN *ORDER* !!!!
792void MainWindow2::setSegType(const QString &t)
793{
794    // live change of selected segment
795    curSegType =   t;
796
797        // Now set the type of the way if a way is selected, rather than a segment
798        if(selWay)
799                selWay->setType(curSegType);
800        else
801        {
802                for(int count=0; count<selSeg.size(); count++)
803                        selSeg[count]->setType(curSegType);
804        }
805
806        // UPLOAD IF IN LIVE MODE
807        if(liveUpdate)
808        {
809                        if(selWay)
810                        {
811                QByteArray xml = selWay->toOSM();
812                QString url;
813                url.sprintf ("/api/0.3/way/%d", selWay->getOSMID());
814                osmhttp.setAuthentication(username, password);
815                                osmhttp.scheduleCommand("PUT",url,xml);
816                        }
817                        else if(!makingWay)
818                        {
819                                for(int ct=0; ct<selSeg.size(); ct++)
820                                {
821                        QByteArray xml = selSeg[ct]->toOSM();
822                        QString url;
823                        url.sprintf("/api/0.3/segment/%d",selSeg[ct]->getOSMID());
824                        osmhttp.setAuthentication(username, password);
825                                        osmhttp.scheduleCommand("PUT",url,xml);
826                                }
827                        }
828        }
829    update();
830}
831*/
832
833void MainWindow2::toggleNodes()
834{
835    trackpoints = !trackpoints;
836    update();
837}
838
839void MainWindow2::toggleLandsat()
840{
841        landsatButton->setOn(landsatManager.toggleDisplay());
842    update();
843}
844
845void MainWindow2::toggleOSM()
846{
847        displayOSM = !displayOSM;
848        osmButton->setOn(displayOSM);
849    update();
850}
851
852void MainWindow2::toggleGPX()
853{
854        displayGPX = !displayGPX;
855        gpxButton->setOn(displayGPX);
856    update();
857}
858
859void MainWindow2::toggleContours()
860{
861    contours = !contours;
862        contoursButton->setOn(contours);
863    update();
864}
865
866void MainWindow2::toggleSegmentColours()
867{
868        showSegmentColours = !showSegmentColours; 
869        showSegmentColoursButton->setOn(showSegmentColours);
870    update();
871}
872
873void MainWindow2::undo()
874{
875    //TODO
876    update();       
877}
878
879void MainWindow2::paintEvent(QPaintEvent* ev)
880{
881    QPainter p(this);
882    drawLandsat(p);
883        drawAreas(p);
884        drawGPX(p);
885    curPainter = &p; // needed for the contour "callback"
886    drawContours();
887        drawTrackPoints(p,components,QColor(255,128,192),true);
888    drawSegments(p);
889    drawNodes(p);
890    curPainter = NULL;
891    if(movingNode)
892    {
893            /*
894        bitBlt(this,0,0, &savedPixmap,0,0,savedPixmap.width(),
895                        savedPixmap.height(), Qt::CopyROP);
896                        */
897        drawMoving(p);
898    }
899}
900
901void MainWindow2::drawLandsat(QPainter& p)
902{
903    landsatManager.drawTilesNew(p);
904}
905
906void MainWindow2::drawContours()
907{
908    if(contours)
909    {
910        SRTMConGen congen(map,1);
911        congen.generate(this);
912    }
913}
914
915void MainWindow2::drawContour(int x1,int y1,int x2,int y2,int r,int g,int b)
916{
917    if(curPainter)
918    {
919        curPainter->setPen(QColor(r,g,b));
920        curPainter->drawLine(x1,y1,x2,y2);
921    }
922}
923
924void MainWindow2::drawAngleText(int fontsize,double angle,int x,int y,int r,
925                                int g, int b, char *text)
926{
927    if(curPainter)
928    {
929        //angle*=-180/M_PI;
930        curPainter->setFont(QFont("Helvetica",fontsize));
931        doDrawAngleText(curPainter,x,y,x,y,angle,text);
932    }
933}
934
935void MainWindow2::doDrawAngleText(QPainter *p,int originX,int originY,int x,
936                int y,double angle, const char * text)
937{
938    angle *= 180/M_PI;
939    p->translate(originX,originY);
940    p->rotate(angle);
941    p->drawText(x-originX,y-originY,text);
942    p->rotate(-angle);
943    p->translate(-originX,-originY);
944}
945
946void MainWindow2::heightShading(int x1,int y1,int x2,int y2,int x3,int y3,
947                                int x4,int y4,int r,int g, int b)
948{
949
950}
951
952void MainWindow2::drawAreas(QPainter& p)
953{
954        if(displayOSM)
955        {
956                for(int count=0; count<components->nAreas(); count++)
957                        drawArea(p,components->getArea(count));
958        }
959}
960
961// draw an area
962// WARNING! All segments must be orientated in the same direction for this
963// to work!!!
964void MainWindow2::drawArea(QPainter& p, Area *area)
965{
966        cerr << "area type: " << area->getType() << endl;
967        if(areapens.find(area->getType()) != areapens.end())
968        {
969                cerr << "that type exists!" << endl;
970                QPen pen = areapens[area->getType()];
971                p.setPen(pen);
972                p.setBrush(QBrush(pen.color(),Qt::SolidPattern));
973
974                QPointArray pointarray(area->nSegments()+1);
975                ScreenPos pos;
976
977                int count=0, added=0;
978                while(!area->getSegment(count) && count<area->nSegments())
979                {
980                        count++;
981                }
982
983                if(count<area->nSegments())
984                {
985                        pos = map.getScreenPos
986                                (area->getSegment(count)->firstNode()->getLon(),
987                                 area->getSegment(count)->firstNode()->getLat());
988                        pointarray.setPoint(added++,pos.x,pos.y);
989                }
990
991                while(count<area->nSegments())
992                {
993                        if(area->getSegment(count))
994                        {
995                                pos = map.getScreenPos
996                                (area->getSegment(count)->secondNode()->getLon(),
997                                 area->getSegment(count)->secondNode()->getLat());
998                                pointarray.setPoint(added++,pos.x,pos.y);
999                        }
1000                        count++;
1001                }
1002
1003                p.drawPolygon(pointarray,false,0,added);
1004                p.setBrush(Qt::NoBrush);
1005        }
1006}
1007
1008void MainWindow2::drawSegments(QPainter& p)
1009{
1010        if(displayOSM)
1011        {
1012        Segment *curSeg;
1013        QString segname;
1014
1015
1016                for(int count=0; count<components->nSegments(); count++)
1017        {
1018                drawSegment(p,components->getSegment(count));
1019        }
1020        }
1021}
1022
1023void MainWindow2::drawSegment(QPainter& p, Segment *curSeg)
1024{
1025        ScreenPos pt1, pt2;
1026        double dx, dy;
1027        QFont f("Helvetica",10,QFont::Bold,false);
1028        QFontMetrics fm(f);
1029        p.setFont(f);
1030
1031                bool found = false, foundWay = false;
1032
1033                for(int count=0; count<selSeg.size(); count++)
1034                {
1035                        if(curSeg==selSeg[count])
1036                        {
1037                                found=true;
1038                                break;
1039                        }
1040                }
1041
1042                if(selWay && components->getWayByID(curSeg->getWayID())==selWay)
1043                {
1044                        foundWay=true;
1045                }
1046
1047                // 030706 draw only ways in colours. un-wayed segments shown in
1048                // a neutral colour to encourage way tagging and make things clearer.
1049               
1050        QPen curPen = (foundWay) ? QPen(QColor(255,170,0),5) : ( (found) ?
1051                        QPen(Qt::yellow,5) : QPen(QColor(128,128,128),1) );
1052
1053        curPen.setStyle ((curSeg->getOSMID()>0) ?  Qt::SolidLine: Qt::DotLine );
1054               
1055        if(curSeg->hasNodes())
1056        {
1057            pt1=map.getScreenPos(curSeg->firstNode()->getLon(),
1058                                curSeg->firstNode()->getLat());
1059            pt2=map.getScreenPos(curSeg->secondNode()->getLon(),
1060                                curSeg->secondNode()->getLat());
1061            if(map.pt_within_map(pt1) || map.pt_within_map(pt2))
1062            {
1063                                // Draw segments belonging to ways (only) in the correct colour
1064                                if(curSeg->belongsToWay() && !found && !foundWay)
1065                                {
1066
1067                                        Way *w=components->getWayByID(curSeg->getWayID());
1068                                        //curPen = segpens[curSeg->getType()].pen;
1069                                        if(segpens.find(w->getType()) != segpens.end())
1070                                        {
1071                                                curPen = segpens[w->getType()].pen;
1072
1073                                                if(segpens[w->getType()].casing)
1074                                                {
1075                                                        p.setPen(QPen(Qt::black,curPen.width()+2));
1076                                        p.drawLine(pt1.x,pt1.y,pt2.x,pt2.y);
1077                                                /*
1078                                p.drawEllipse( pt1.x - 5, pt1.y - 5, 10, 10 );
1079                                p.drawEllipse( pt2.x - 5, pt2.y - 5, 10, 10 );
1080                                                */
1081
1082                                                //cerr<<"segment belongs to a way"<<endl;
1083                                                //curPen.setWidth(4);
1084                                                }
1085                                        }
1086
1087                                        // If the segment is the longest segment in a way, draw its
1088                                        // name
1089                                        if(w->getName()!="")
1090                                        {
1091                                                dy=pt2.y-pt1.y;
1092                                                dx=pt2.x-pt1.x;
1093                                                if(w && fm.width(w->getName()) <=fabs(dx) &&
1094                                                                        curSeg==w->longestSegment())
1095                                                {
1096                                double angle = atan2(dy,dx);
1097                                doDrawAngleText(&p,pt1.x,pt1.y,pt1.x,pt1.y,
1098                                angle,w->getName().ascii());
1099                                                }
1100                        }
1101                                }
1102                                // If the user has selected to display unwayed segments in
1103                                // colour, find the appropriate colour.
1104                                else if (showSegmentColours && !found && !foundWay) 
1105                                {
1106                                        cerr << "FOUND A SEG TO COLOUR*** " ;
1107                                        cerr << "Type: "<< curSeg->getType() << endl;
1108                                        if(segpens.find(curSeg->getType()) != segpens.end())
1109                                        {
1110                                                curPen = segpens[curSeg->getType()].pen;
1111                                                curPen.setWidth(1); // unwayed segments always 1
1112                                        }
1113                                }
1114
1115                                int s = (curSeg->belongsToWay()) ? 4:8;
1116                        p.setPen(curPen);
1117                p.drawLine(pt1.x,pt1.y,pt2.x,pt2.y);
1118                                p.setBrush(Qt::SolidPattern);
1119                        //p.setPen(Qt::black);
1120                                p.fillRect( pt1.x-s/2, pt1.y-s/2, s, s, QColor(128,128,128) );
1121                                p.fillRect( pt2.x-s/2, pt2.y-s/2, s, s, QColor(128,128,128) );
1122                                //p.drawEllipse( pt2.x - 4, pt2.y - 4, 8, 8 );
1123            }
1124        }
1125}
1126
1127void MainWindow2::drawGPX(QPainter& p)
1128{
1129        if(displayGPX)
1130        {
1131                drawTrackPoints(p,osmtracks,QColor(255,192,128),false);
1132        }
1133}
1134
1135void MainWindow2::drawNodes(QPainter& p)
1136{
1137        if(displayOSM)
1138        {
1139                for(int count=0; count<components->nNodes(); count++)
1140        {
1141                drawNode(p,components->getNode(count));
1142        }
1143        }
1144}
1145
1146void MainWindow2::drawTrackPoints(QPainter& p,Components2 *comp,QColor colour,
1147                                                                        bool join)
1148{
1149        TrackPoint *prev = NULL, *current;
1150        ScreenPos prevPos, currentPos;
1151        QString idAsText;
1152
1153        for(int count=0; count<comp->nTrackPoints(); count++)
1154    {
1155                current = comp->getTrackPoint(count);
1156        currentPos = map.getScreenPos(current->getLon(),current->getLat());
1157                if(prev)
1158                {
1159                        p.setPen ( (count>tpts[0] && count<=tpts[1] && comp==components ) ?
1160                                        QPen(colour,3): QPen(colour,1) );
1161                        if(join && OpenStreetMap::dist(current->getLat(),current->getLon(),
1162                                                                        prev->getLat(),prev->getLon() ) <= 0.05)
1163                        {
1164                                p.drawLine(prevPos.x,prevPos.y,currentPos.x,currentPos.y);
1165                        }
1166                }
1167                int r = (count==tpts[0] || count==tpts[1] && comp==components ) ? 8:4;
1168                p.setBrush((count==tpts[0] || count==tpts[1] && comp==components ) ? 
1169                                                Qt::SolidPattern: Qt::NoBrush);
1170                p.drawEllipse(currentPos.x-r/2,currentPos.y-r/2,r,r);
1171
1172                if(comp==components)
1173                {
1174                        idAsText.sprintf("%d", count);
1175                        //p.drawPixmap(currentPos.x,currentPos.y,tpPixmap);
1176                        p.setFont(QFont("Helvetica",8));
1177                        p.drawText(currentPos.x+3,currentPos.y+3,idAsText);
1178                }
1179
1180                prev = current;
1181                prevPos = currentPos;
1182    }
1183}
1184
1185void MainWindow2::drawMoving(QPainter& p)
1186{
1187    drawNode(p,movingNode);
1188    for(int count=0; count<movingNodeSegs.size(); count++)
1189        drawSegment(p,movingNodeSegs[count]);
1190}
1191
1192void MainWindow2::drawNode(QPainter& p,Node* node)
1193{
1194    ScreenPos pos = map.getScreenPos(node->getLon(),node->getLat());
1195    if(map.pt_within_map(pos))
1196    {
1197                vector<Segment*> containingSegs = components->getSegs(node);
1198
1199                // don't draw nodes of type 'node' which belong to segments
1200                if((containingSegs.empty()||node->getType()!="node") &&
1201                                nodeReps.find(node->getType()) != nodeReps.end())
1202                {
1203                WaypointRep* img=nodeReps[node->getType()];
1204                if(img) img->draw(p,pos.x,pos.y,node->getName());
1205
1206                if(node==pts[0] || node==pts[1] || node==movingNode)
1207                {
1208                p.setPen(QPen(Qt::red,3));
1209                                p.setBrush(Qt::NoBrush);
1210                p.drawEllipse( pos.x - 16, pos.y - 16, 32, 32 );
1211                }
1212                }
1213    }
1214}
1215
1216void MainWindow2::drawTrackPoint(QPainter &p,TrackPoint *tp)
1217{
1218}
1219
1220void MainWindow2::removeTrackPoints()
1221{
1222    components->removeTrackPoints();
1223    update();
1224}
1225
1226void MainWindow2::mousePressEvent(QMouseEvent* ev)
1227{
1228    EarthPoint p = map.getEarthPoint(ScreenPos(ev->x(),ev->y()));
1229    QString name;
1230    int nearest;
1231    Node *n;
1232        Segment *s1;
1233
1234    switch(actionMode)
1235    {
1236        case ACTION_NODE:
1237            editNode(ev->x(),ev->y(),LIMIT);       
1238            break;
1239
1240        case ACTION_MOVE_NODE:
1241            movingNode = components->getNearestNode(p.y,p.x,LIMIT);
1242            if(movingNode)
1243            {
1244                movingNodeSegs = components->getSegs(movingNode);
1245                //components->deleteNode(movingNode);
1246                movingNodes.clear();
1247                for(int count=0; count<movingNodeSegs.size(); count++)
1248                {
1249                    if(movingNodeSegs[count]->firstNode()!=movingNode)
1250                    {
1251                        movingNodes.push_back
1252                                (movingNodeSegs[count]->firstNode());
1253                    }
1254                    else
1255                    {
1256                        movingNodes.push_back
1257                                (movingNodeSegs[count]->secondNode());
1258                    }
1259                }
1260                movingNodes.push_back(movingNode);
1261                repaint(false);
1262            }
1263            break;
1264        case ACTION_DELETE_NODE:
1265            n = components->getNearestNode(p.y,p.x,LIMIT);
1266            if(n)
1267            {
1268                QString url;
1269                components->deleteNode(n);
1270                if(liveUpdate && n->getOSMID()>0)
1271                {
1272                    url.sprintf ("/api/0.3/node/%d", n->getOSMID());
1273                    osmhttp.setAuthentication(username, password);
1274                    osmhttp.scheduleCommand("DELETE", url);
1275                }
1276               
1277                // If this node is part of any segments, delete the segments
1278                vector<Segment*> containingSegs = components->getSegs(n);
1279                for(int count=0; count<containingSegs.size(); count++)
1280                {
1281                        components->deleteSegment(containingSegs[count]);
1282                        /* Deleting a node will effectively delete the
1283                         * segments on the server - so no need to do this
1284                         *
1285                        if(liveUpdate&&containingSegs[count]->getOSMID()>0)
1286                        {
1287                            url.sprintf ("/api/0.2/segment/%d",
1288                                    containingSegs[count]->getOSMID());
1289                            osmhttp.scheduleCommand("DELETE", url);
1290                        }
1291                        */
1292                        delete containingSegs[count];
1293                }
1294               
1295                delete n;
1296                update();
1297            }
1298            break;
1299        case ACTION_NEW_SEG:
1300            if(nSelectedPoints==0)
1301            {
1302                pts[0] = components->getNearestNode(p.y,p.x,LIMIT);
1303                if(!pts[0] || pts[0]->getOSMID()<=0)
1304                    pts[0]=doAddNewNode(p.y,p.x,"","node");
1305                update();
1306                nSelectedPoints++;
1307            }
1308            else
1309            {
1310                pts[1] = components->getNearestNode(p.y,p.x,LIMIT);
1311                if(!pts[1] || pts[1]->getOSMID()<=0)
1312                                {
1313                                        pts[1] = components->addNewNode(p.y,p.x,"","node");
1314                        Segment *segx= components->addNewSegment (pts[0],pts[1]);
1315                                        nodeHandler.setEmit
1316                                                        (segx,this,SLOT(doaddseg(void*)));
1317                                        if(liveUpdate)
1318                                        {
1319                                                QByteArray xml = pts[1]->toOSM();
1320                                                QString url = "/api/0.3/node/0";
1321                                                osmhttp.setAuthentication(username, password);
1322                                                newUploadedNode = pts[1];
1323                                                osmhttp.scheduleCommand("PUT",url,xml,
1324                                                        &nodeHandler,
1325                                                        SLOT(newNodeAdded(const QByteArray&,void*)),
1326                                                        newUploadedNode,
1327                                                        SLOT(handleNetCommError(const QString&)), this);
1328                                        }
1329                                }
1330                                else
1331                                {
1332                        Segment *segx=
1333                                            components->addNewSegment(pts[0],pts[1]);
1334                                        doaddseg(segx);
1335                                }
1336
1337                pts[0]=pts[1]=NULL;
1338                nSelectedPoints=0;
1339
1340                                update();
1341                        }
1342
1343                               
1344                                       
1345            break;
1346                case ACTION_BREAK_SEG:
1347                        if(selSeg.size()==1 && splitter==NULL)
1348                        {
1349                                splitter = new SegSplitter;
1350                                splitter->setComponents(components);
1351                                splitter->setHTTPHandler(&osmhttp);
1352                                splitter->splitSeg(selSeg[0],p,LIMIT);
1353                                QObject::connect(splitter,SIGNAL(done()),this,
1354                                                                        SLOT(splitterDone()));
1355                                QObject::connect(splitter,SIGNAL(error(const QString&)),this,
1356                                                                        SLOT(segSplitterError(const QString&)));
1357                        }
1358                        break;
1359
1360        case  ACTION_SEL_SEG:
1361                case  ACTION_SEL_WAY:
1362
1363                        /* NEW CODE TO SELECT SEGMENT DIRECTLY RATHER THAN VIA NODES */
1364
1365                        // 280306 only push back the new segment if we're making a
1366                        // way if the current last segment is not NULL. In this
1367                        // way, we can re-use the current last segment if selection
1368                        // of the last segment was unsuccessful.
1369                       
1370                        /*
1371                        if(makingWay && segCount!=0 && selSeg[segCount]!=NULL)
1372                                selSeg.push_back(NULL);
1373                        */
1374
1375                        s1= components->getNearestSegment(p.y,p.x,LIMIT);
1376                        if(s1)
1377                        {
1378                                cerr<<"getNearestSegment: ID=" << s1->getOSMID() << endl;
1379                                       
1380                                // If we're in way select mode, select the whole
1381                                // parent way of the segment
1382                                if(actionMode==ACTION_SEL_WAY)
1383                                {
1384                                        cerr<<"mode=ACTION_SEL_WAY" << endl;
1385                                        clearSegments();
1386                                        int wayID = s1->getWayID();
1387                                        if(wayID)
1388                                        {
1389                                                cerr<<"wayID=" << wayID << endl;
1390                                                selWay = components->getWayByID(wayID);
1391                                        }
1392                                }
1393                                // Otherwise, just select the segment
1394                                else
1395                                {
1396                                        if(!makingWay)
1397                                                clearSegments();
1398                                        selWay = NULL;
1399                                        selSeg.push_back(s1);
1400                                        if(makingWay)
1401                                        {
1402                                                for(int ct=0; ct<selSeg.size(); ct++)
1403                                                        if(selSeg[ct])cerr<< selSeg[ct]->getOSMID() << " ";
1404                                                cerr<<endl;
1405                                        }
1406                                }
1407                        }
1408                        update();
1409            break;
1410        case ACTION_SEL_TRACK:
1411            if(nSelectedTrackPoints==0)
1412            {
1413                if((tpts[0] = components->getNearestTrackPoint(p.y,p.x,LIMIT))
1414                                                >=0)
1415                                {
1416                        nSelectedTrackPoints++;
1417                                        tpts[1] = -1;
1418                                        update();
1419                                }
1420            }
1421            else
1422            {
1423                tpts[1] = components->getNearestTrackPoint(p.y,p.x,LIMIT);
1424                                if(tpts[1]>=0)
1425                                {
1426                                        nSelectedTrackPoints = 0;
1427                                        update();
1428                                }
1429                        }
1430
1431            break;
1432    }               
1433}
1434
1435void MainWindow2::resizeEvent(QResizeEvent * ev)
1436{
1437    //map.resizeTopLeft(ev->size().width(), ev->size().height());
1438    map.resizeTopLeft(width(), height());
1439    //landsatManager.grab();
1440    //landsatManager.resize(ev->size().width(), ev->size().height());
1441    landsatManager.resize(width(), height());
1442    update();
1443    LIMIT=map.earthDist(10);
1444}
1445
1446
1447void MainWindow2::editNode(int x,int y,int limit)
1448{
1449    Node *nearest = NULL;   
1450    WaypointDialogue *d;
1451
1452    EarthPoint p = map.getEarthPoint(ScreenPos(x,y));
1453    if((nearest=components->getNearestNode(p.y,p.x,LIMIT)) != NULL)
1454    {
1455        d = new WaypointDialogue
1456                    (this,nodeReps,"Edit node",
1457                    nearest->getType(),nearest->getName());
1458        if(d->exec())
1459        {
1460            nearest->setName(d->getName());
1461            nearest->setType(d->getType());
1462            if(liveUpdate && nearest->getOSMID()>0)
1463            {
1464                //nearest->uploadToOSM(username,password);
1465                QByteArray xml = nearest->toOSM();
1466                QString url;
1467                url.sprintf ("/api/0.3/node/%d", nearest->getOSMID());
1468                osmhttp.setAuthentication(username, password);
1469                osmhttp.scheduleCommand("PUT", url, xml);
1470            }
1471        }
1472
1473        update();
1474        delete d;
1475    }
1476    else
1477    {
1478        d = new WaypointDialogue
1479                    (this,nodeReps,"Add node","node","");
1480        if(d->exec())
1481        {
1482                        doAddNewNode(p.y,p.x,d->getName(),d->getType());
1483                }
1484
1485        update();
1486        delete d;
1487    }
1488}
1489
1490void MainWindow2::mouseMoveEvent(QMouseEvent* ev)
1491{
1492    EarthPoint p = map.getEarthPoint(ScreenPos(ev->x(),ev->y()));
1493    switch(actionMode)
1494    {
1495        case ACTION_MOVE_NODE:
1496            if(movingNode)
1497            {
1498
1499                movingNode->setCoords(p.y,p.x);
1500
1501                ScreenPos min, max, cur;
1502                min.x=width(); min.y=height(); max.x=0; max.y=0;
1503
1504                for(int count=0; count<movingNodes.size(); count++)
1505                {
1506                    cur = map.getScreenPos(movingNodes[count]->getLon(),
1507                                            movingNodes[count]->getLat());
1508                    if(cur.x<min.x)
1509                        min.x=cur.x;
1510                    if(cur.y<min.y)
1511                        min.y=cur.y;
1512                    if(cur.x>max.x)
1513                        max.x=cur.x;
1514                    if(cur.y>max.y)
1515                        max.y=cur.y;
1516                }
1517
1518                repaint(min.x-19,min.y-19,(max.x-min.x)+38,(max.y-min.y)+38);
1519            }
1520    }
1521}
1522
1523void MainWindow2::mouseReleaseEvent(QMouseEvent* ev)
1524{
1525    EarthPoint p = map.getEarthPoint(ScreenPos(ev->x(),ev->y()));
1526    QString name;
1527    double LIMIT=map.earthDist(10);
1528    switch(actionMode)
1529    {
1530        case ACTION_MOVE_NODE:
1531            if(movingNode)
1532            {
1533                movingNode->setCoords(p.y,p.x);
1534                //components->addNode(movingNode);
1535                if(liveUpdate && movingNode->getOSMID()>0)
1536                {
1537                    QByteArray xml = movingNode->toOSM();
1538                    QString url;
1539                    url.sprintf ("/api/0.3/node/%d", movingNode->getOSMID());
1540                    osmhttp.setAuthentication(username, password);
1541                    osmhttp.scheduleCommand("PUT", url, xml);
1542                }
1543                movingNode = NULL;     
1544                movingNodeSegs.clear();
1545                update();
1546            }
1547    }
1548}
1549
1550void MainWindow2::keyPressEvent(QKeyEvent* ev)
1551{
1552    bool typingName = false;
1553
1554    if(doingName)
1555    {
1556        if(ev->ascii()>=32 && ev->ascii()<=127)
1557        {
1558            trackName += ev->text();
1559            QPainter p(this);
1560            p.setPen(Qt::black);
1561            QFont f ("Helvetica",10,QFont::Bold,true);
1562            p.setFont(f);
1563            QFontMetrics fm(f);
1564
1565            doDrawAngleText(&p,namePos.x,namePos.y,curNamePos.x,
1566                            curNamePos.y,
1567                            -nameAngle,ev->text());
1568            curNamePos.x += fm.width(ev->text());
1569            typingName = true;
1570        }
1571        else if (ev->key()==Key_Return && selSeg.size()==1)
1572        {
1573            selSeg[0]->setName(trackName);
1574//              UPLOAD IF IN LIVE MODE
1575            if(liveUpdate)
1576            {
1577                //selSeg->uploadToOSM(username,password);
1578                QByteArray xml = selSeg[0]->toOSM();
1579                QString url;
1580                url.sprintf ("/api/0.3/segment/%d", 
1581                                        selSeg[0]->getOSMID());
1582                osmhttp.setAuthentication(username, password);
1583                osmhttp.scheduleCommand("PUT", url, xml);
1584            }
1585            trackName = "";
1586            typingName = true;
1587            update();
1588        }
1589    }
1590
1591    switch(ev->key())
1592    {
1593        case Qt::Key_Left  : left(); break;
1594        case Qt::Key_Right : right(); break;
1595        case Qt::Key_Up    : up(); break;
1596        case Qt::Key_Down  : down(); break;
1597    }
1598
1599    // Now use CTRL for the shortcuts so it doesn't interfere with
1600    // entering text and you can scale up and down etc when entering text
1601    if(ev->state()==Qt::ControlButton)
1602    {
1603        // 11/04/05 prevent movement being too far at large scales
1604        double dis = 0.1/map.getScale();
1605
1606        switch(ev->key())
1607        {
1608            case Qt::Key_Plus  : magnify(); break;
1609            case Qt::Key_Minus : shrink(); break;
1610                                 
1611            // Remember the ZX Spectrum? :-)
1612            case Qt::Key_5     : screenLeft(); break;
1613            case Qt::Key_6     : screenDown(); break;
1614            case Qt::Key_7     : screenUp(); break;
1615            case Qt::Key_8     : screenRight(); break;
1616        }
1617    }
1618}
1619
1620void MainWindow2::left()
1621{
1622    map.movePx(-landsatManager.getTileSize(),0);
1623    landsatManager.left();
1624    showPosition();
1625    update();
1626}
1627
1628void MainWindow2::right()
1629{
1630    map.movePx(landsatManager.getTileSize(),0);
1631    landsatManager.right();
1632    showPosition();
1633    update();
1634}
1635
1636void MainWindow2::up()
1637{
1638    map.movePx(0,-landsatManager.getTileSize());
1639    landsatManager.up();
1640    showPosition();
1641    update();
1642}
1643
1644void MainWindow2::down()
1645{
1646    map.movePx(0,landsatManager.getTileSize());
1647    landsatManager.down();
1648    showPosition();
1649    update();
1650}
1651
1652void MainWindow2::screenLeft()
1653{
1654    map.movePx(-width(),0);
1655    landsatManager.grabAll();
1656    showPosition();
1657    update();
1658}
1659
1660void MainWindow2::screenRight()
1661{
1662    map.movePx(width(),0);
1663    landsatManager.grabAll();
1664    showPosition();
1665    update();
1666}
1667
1668void MainWindow2::screenUp()
1669{
1670    map.movePx(0,-height());
1671    landsatManager.grabAll();
1672    showPosition();
1673    update();
1674}
1675
1676void MainWindow2::screenDown()
1677{
1678    map.movePx(0,height());
1679    landsatManager.grabAll();
1680    showPosition();
1681    update();
1682}
1683
1684void MainWindow2::magnify()
1685{
1686    map.rescale(2);
1687        landsatManager.clearTiles();
1688    landsatManager.grabAll();
1689    showPosition();
1690    update();
1691    LIMIT=map.earthDist(10);
1692}
1693
1694void MainWindow2::shrink()
1695{
1696    map.rescale(0.5);
1697        landsatManager.clearTiles();
1698    landsatManager.grabAll();
1699    showPosition();
1700    update();
1701    LIMIT=map.earthDist(10);
1702}
1703
1704void MainWindow2::updateWithLandsatCheck()
1705{
1706                /*
1707    if(landsatManager.needMoreData())
1708        landsatManager.forceGrab();
1709    showPosition();
1710    update();
1711        */
1712}
1713
1714void MainWindow2::grabLandsat()
1715{
1716    // 01/05/05 grab three times current screen width and height (i.e. 9
1717    // times screen area) and centre at current
1718    // map centre. This will be configurable.
1719   
1720
1721    //landsatManager.forceGrab();
1722    landsatManager.forceGrabAll();
1723    update();
1724
1725
1726}
1727
1728void MainWindow2::nameTrackOn()
1729{
1730
1731    if(selSeg.size()==1)
1732    {
1733        Node *n1 = selSeg[0]->firstNode(), 
1734                        *n2 = selSeg[0]->secondNode();
1735        double dy=n2->getLat()-n1->getLat();
1736        double dx=n2->getLon()-n1->getLon();
1737        nameAngle = atan2(dy,dx);
1738        doingName = true;
1739        namePos = map.getScreenPos (n1->getLon(),n1->getLat());
1740        curNamePos = namePos;
1741        trackName="";
1742        update();
1743    }
1744}
1745
1746// ripped off from Mapmaker
1747
1748QPixmap mmLoadPixmap(const QString& directory, const QString& filename)
1749{
1750    QString fullpath;
1751
1752    if (directory != "")
1753    {
1754        fullpath = directory+"/"+filename;
1755    }
1756    else
1757    {
1758        fullpath=filename;
1759    }
1760
1761    QPixmap pixmap (fullpath);
1762
1763    // if (pixmap.isNull()) ...
1764           
1765
1766    return pixmap;
1767}
1768
1769
1770void MainWindow2::newSegmentAdded(const QByteArray& array, void *segment)
1771{
1772        Segment *seg = (Segment*) segment;
1773        //Segment *seg=newUploadedSegment;
1774    QString str = array;
1775    QStringList ids;
1776    ids = QStringList::split("\n", str);
1777    if(seg)
1778    {
1779        cerr<<"NEW UPLOADED SEGMENT IS NOT NULL::SETTING ID"<<endl;
1780                cerr<<"ID IS: " << atoi(ids[0].ascii()) << endl;
1781        seg->setOSMID(atoi(ids[0].ascii()));
1782        newUploadedSegment = NULL;
1783        cerr<<"DONE."<<endl;
1784    }
1785    update();
1786}
1787
1788void MainWindow2::newWayAdded(const QByteArray& array,void *way)
1789{
1790        Way *w=(Way*)way;
1791        //Way *w=newUploadedWay;
1792    QString str = array;
1793    QStringList ids;
1794    ids = QStringList::split("\n", str);
1795    if(w)
1796    {
1797        cerr<<"NEW UPLOADED Way/Area IS NOT NULL::SETTING ID"<<endl;
1798                cerr<<"ID = "<< atoi(ids[0].ascii()) << endl;
1799        w->setOSMID(atoi(ids[0].ascii()));
1800
1801                // TEMPORARY
1802                //delete newUploadedWay;
1803
1804        newUploadedWay = NULL;
1805        cerr<<"DONE."<<endl;
1806    }
1807    update();
1808}
1809
1810void MainWindow2::deleteSelectedSeg()
1811{
1812        // Now deletes a way if a way is selected
1813    if(actionMode==ACTION_SEL_SEG && selSeg.size()==1)
1814    {
1815        cerr<<"selseg exists" << endl;
1816        components->deleteSegment(selSeg[0]);
1817        if(liveUpdate && selSeg[0]->getOSMID()>0)
1818        {
1819            QString url;
1820                        int wayID;
1821            url.sprintf ("/api/0.3/segment/%d", selSeg[0]->getOSMID());
1822            osmhttp.setAuthentication(username, password);
1823            osmhttp.scheduleCommand("DELETE", url);
1824
1825                        // 180506 If the segment is in a way, remove the segment from the
1826                        // way and upload the changes to OSM
1827                        if(wayID=selSeg[0]->getWayID())
1828                        {
1829                                Way *w = components->getWayByID(wayID);
1830                                w->removeSegment(selSeg[0]);
1831                url.sprintf ("/api/0.3/way/%d", wayID);
1832                                osmhttp.scheduleCommand("PUT",url);
1833                        }
1834        }
1835                cerr<<"deleteSelectedSeg(): setting segmnet to NULL" << endl;
1836        delete selSeg[0];
1837        selSeg.clear();
1838        update();
1839    }
1840        else if (actionMode==ACTION_SEL_WAY && selWay)
1841        {
1842        components->deleteWay(selWay);
1843        if(liveUpdate && selWay->getOSMID()>0)
1844        {
1845            QString url;
1846            url.sprintf ("/api/0.3/way/%d", selWay->getOSMID());
1847            osmhttp.setAuthentication(username, password);
1848            osmhttp.scheduleCommand("DELETE", url);
1849        }
1850        delete selWay;
1851        selWay = NULL;
1852        update();
1853        }
1854        // 060706 now also deletes GPX track if selected
1855        else if (actionMode==ACTION_SEL_TRACK && tpts[0]>=0 && tpts[1]>=0)
1856        {
1857                components->deleteTrackPoints(tpts[0],tpts[1]);
1858                tpts[0] = tpts[1] = -1;
1859                update();
1860        }
1861}
1862
1863void MainWindow2::handleHttpError(int code,const QString& reasonPhrase)
1864{
1865    if(code!=410)
1866    {
1867        QString errMsg;
1868        errMsg.sprintf("Error: %d ",code);
1869        errMsg += reasonPhrase;
1870        QMessageBox::information(this,
1871                        "An error occurred communicating with OSM",
1872                                errMsg);
1873    }
1874}
1875
1876void MainWindow2::handleNetCommError(const QString& error)
1877{
1878    QMessageBox::information(this,
1879                "An error occurred communicating with OSM", error);
1880}
1881
1882void MainWindow2::showPosition()
1883{
1884        QString msg;
1885        msg.sprintf("Lat %lf Long %lf",
1886                        map.getBottomLeft().y, map.getBottomLeft().x);
1887        if(username!="" && password!="")
1888            msg+=" Logged in - live update active!";
1889        statusBar()->message(msg);
1890}
1891
1892void MainWindow2::toggleWays()
1893{
1894        makingWay = !makingWay; 
1895        wayButton->setOn(makingWay);
1896        cerr<<"toggleWays(): CLEARING SEGMENTS"<<endl;
1897        clearSegments();
1898}
1899
1900// uploadWay()
1901// also uploads areas
1902
1903void MainWindow2::uploadWay()
1904{
1905        Way *way = new Way(components);
1906        way->setSegments(selSeg);
1907        vector<QString> segTypes, areaTypes;
1908
1909        for(std::map<QString,SegPen>::iterator i=segpens.begin(); 
1910                                                i!=segpens.end(); i++)
1911        {
1912                segTypes.push_back(i->first);
1913        }
1914        for(std::map<QString,QPen>::iterator i=areapens.begin(); i!=areapens.end();
1915        i++)
1916        {
1917                areaTypes.push_back(i->first);
1918        }
1919
1920        WayDialogue *wd = new WayDialogue(this,segTypes,areaTypes);
1921        if(wd->exec())
1922        {
1923                way->setName(wd->getName());
1924                way->setType(wd->getType());
1925                way->setRef(wd->getRef()); // areas shouldn't have refs really
1926                way->setArea(wd->isArea());
1927                QByteArray xml = way->toOSM();
1928                cerr<<"way xml is: "<<xml<<endl;
1929                if(wd->isArea())
1930                        components->addArea((Area*)way);
1931                else
1932                        components->addWay(way);
1933                cerr<<"uploadWay(): CLEARING SEGMENTS"<<endl;
1934                clearSegments();
1935                if(liveUpdate)
1936                {
1937                        QString url = wd->isArea() ? "/api/0.3/area/0" :
1938                                                                                "/api/0.3/way/0";
1939                        //url.sprintf("/api/0.3/%s/0", type.ascii());
1940
1941                        newUploadedWay = way;
1942                        osmhttp.setAuthentication(username, password);
1943
1944                        osmhttp.scheduleCommand("PUT",url,xml,
1945                                                this,SLOT(newWayAdded(const QByteArray&,void*)),
1946                                                newUploadedWay);
1947                }
1948        }
1949}
1950
1951void MainWindow2::changeWayDetails()
1952{
1953        vector<QString> segTypes, areaTypes;
1954
1955        cerr<<"filling segTypes"<<endl;
1956    for(std::map<QString,SegPen>::iterator i=segpens.begin(); i!=segpens.end();
1957        i++)
1958    {
1959        segTypes.push_back(i->first);
1960    }
1961        cerr<<"filling areaTypes"<<endl;
1962    for(std::map<QString,QPen>::iterator i=areapens.begin(); i!=areapens.end();
1963        i++)
1964    {
1965        areaTypes.push_back(i->first);
1966    }
1967
1968        if(selWay && !selWay->isArea())
1969        {
1970                WayDialogue *wd = new WayDialogue(this,segTypes,areaTypes,
1971                                                                selWay->getName(), selWay->getType(),
1972                                                                selWay->getRef());
1973                if(wd->exec() && !wd->isArea())
1974                {
1975                        selWay->setName(wd->getName());
1976                        selWay->setType(wd->getType());
1977                        selWay->setRef(wd->getRef());
1978                        QByteArray xml = selWay->toOSM();
1979                        if(liveUpdate)
1980                        {
1981                                QString url;
1982                                url.sprintf("/api/0.3/way/%d", selWay->getOSMID());
1983                                osmhttp.setAuthentication(username, password);
1984                                osmhttp.scheduleCommand("PUT",url,xml);
1985                        }
1986                }
1987                delete wd;
1988        }
1989}
1990
1991// doAddNewNode()
1992// 240306
1993// adds a new node to the components and uploads it if in live update mode.
1994
1995Node *MainWindow2::doAddNewNode(double lat,double lon,const QString &name,
1996                                                                        const QString& type)
1997{
1998        cerr<<"doAddNewNode: name=" << name << " type=" << type<<endl;
1999        Node *n = components->addNewNode(lat,lon,name,type);
2000        if(liveUpdate)
2001        {
2002                //n->uploadToOSM(username,password);
2003                QByteArray xml = n->toOSM();
2004                QString url = "/api/0.3/node/0";
2005                osmhttp.setAuthentication(username, password);
2006                osmhttp.scheduleCommand("PUT",url,xml,
2007                                                &nodeHandler,
2008                                                SLOT(newNodeAdded(const QByteArray&,void*)),
2009                                                n,SLOT(handleNetCommError(const QString&)),this);
2010        }
2011        return n;
2012}
2013
2014void MainWindow2::splitterDone()
2015{
2016        if(splitter)
2017        {
2018                delete splitter;
2019                splitter = NULL;
2020                update();
2021        }
2022}
2023
2024void MainWindow2::doaddseg(void *sg)
2025{
2026        nodeHandler.discnnect();
2027        Segment *segx = (Segment*) sg;
2028        cerr<<"doaddseg()"<<endl;
2029        if(segx && liveUpdate && segx->firstNode()->getOSMID()>0 &&
2030                                        segx->secondNode()->getOSMID()>0)
2031        {
2032                QByteArray xml = segx->toOSM();
2033                cerr<<"xml is: "<<xml<<endl;
2034                QString url = "/api/0.3/segment/0";
2035                osmhttp.setAuthentication(username, password);
2036                osmhttp.scheduleCommand("PUT",url,xml,
2037                                                this,SLOT(newSegmentAdded(const QByteArray&,void*)),
2038                                                segx); 
2039        }
2040        segx=NULL;
2041        update();
2042}
2043
2044void MainWindow2::changeSerialPort()
2045{
2046        serialPort = QInputDialog::getText("Enter serial port",
2047                                                "Enter serial port, e.g. /dev/ttyS0 or COM1",
2048                                                QLineEdit::Normal, serialPort);
2049}
2050       
2051void MainWindow2::uploadNewWaypoints()
2052{
2053        vector<Node*> newNodes = components->getNewNodes();
2054
2055        QString url = "/api/0.3/node/0";
2056        osmhttp.setAuthentication(username, password);
2057
2058        for(int count=0; count<newNodes.size(); count++)
2059        {
2060                if(newNodes[count]->getType()!="trackpoint" &&
2061                        newNodes[count]->getType()!="node" &&
2062                        // Stop people uploading those ****** Garmin waypoints !!!!
2063                        newNodes[count]->getName().left(3)!="GRM") 
2064                {
2065                        osmhttp.scheduleCommand("PUT",url,newNodes[count]->toOSM(),
2066                                                                &nodeHandler,
2067                                                                SLOT(newNodeAdded(const QByteArray&,void*)),
2068                                                                newNodes[count],
2069                                                                SLOT(handleNetCommError(const QString&)),
2070                                                                this);
2071                }
2072        }
2073}
2074
2075void MainWindow2::loadOSMTracks(const QByteArray& array,void*)
2076{
2077        //QMessageBox::information(this,"Received data", "GPX data received.");
2078
2079        Components2 * comp;
2080        GPXParser2 parser;
2081    QXmlInputSource source;
2082
2083    source.setData(array);
2084        QXmlSimpleReader reader;
2085        reader.setContentHandler(&parser);
2086        reader.parse(source);
2087        comp = parser.getComponents(); 
2088        if(osmtracks)
2089        {
2090                osmtracks->merge(comp);
2091                delete comp;
2092        }
2093        else
2094        {
2095                osmtracks = comp;
2096        }
2097        showPosition();
2098        update();
2099}
2100
2101// This method uploads a selected section of the GPX track as OSM nodes and
2102// segments.
2103// Loop through all trackpoints, make a node and upload each one
2104// After loading nodes, create and upload the segments between them.
2105void MainWindow2::batchUpload()
2106{
2107        // Only upload if selected GPX track...
2108        if(uploader==NULL && liveUpdate && tpts[0]>=0 && tpts[1]>=0)
2109        {
2110                uploader = new BatchUploader;
2111                QObject::connect(uploader,SIGNAL(done()),this,SLOT(batchUploadDone()));
2112                QObject::connect(uploader,SIGNAL(error(const QString&)),this,
2113                                                SLOT(batchUploadError(const QString&)));
2114                uploader->setComponents(components);
2115                osmhttp.setAuthentication(username,password);
2116                uploader->setHTTPHandler(&osmhttp);
2117                uploader->batchUpload(tpts[0],tpts[1]);
2118    }
2119        else if (tpts[0]<0 || tpts[1]<0)
2120        {
2121                QMessageBox::warning(this,"No track selected", 
2122                                        "ERROR - no track selected!");
2123        }
2124        else if (uploader)
2125        {
2126                QMessageBox::warning(this,"Already doing a batch upload", 
2127                                        "ERROR - already doing a batch upload!");
2128        }
2129        else
2130        {
2131                QMessageBox::warning(this,"Need to be in live update mode", 
2132                                        "ERROR - need to be in live update mode!");
2133        }
2134
2135}
2136
2137void MainWindow2::batchUploadDone()
2138{
2139        if(uploader)
2140        {
2141                delete uploader;
2142                uploader = NULL;
2143                update();
2144        }
2145}
2146
2147void MainWindow2::batchUploadError(const QString& error)
2148{
2149        QMessageBox::warning(this,"Error with batch upload",error);
2150        batchUploadDone();
2151}
2152
2153void MainWindow2::segSplitterError(const QString& error)
2154{
2155        QMessageBox::warning(this,"Error with segment splitting",error);
2156        splitterDone();
2157}
2158
2159}
Note: See TracBrowser for help on using the repository browser.