1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/mapeditor.cpp Sun Jan 30 12:59:06 2005 +0000
1.3 @@ -0,0 +1,3062 @@
1.4 +#include "mapeditor.h"
1.5 +
1.6 +#include <qstatusbar.h>
1.7 +#include <qmessagebox.h>
1.8 +#include <qapplication.h>
1.9 +#include <qpainter.h>
1.10 +#include <qpopupmenu.h>
1.11 +#include <qprinter.h>
1.12 +#include <qpaintdevicemetrics.h>
1.13 +#include <qfile.h>
1.14 +#include <qfiledialog.h>
1.15 +#include <qdir.h>
1.16 +#include <qcolor.h>
1.17 +#include <qcolordialog.h>
1.18 +#include <qbitmap.h>
1.19 +#include <qprocess.h>
1.20 +#include <qinputdialog.h>
1.21 +
1.22 +#include <iostream>
1.23 +#include <stdlib.h>
1.24 +#include <typeinfo>
1.25 +
1.26 +#include "version.h"
1.27 +
1.28 +#include "xml.h"
1.29 +#include "texteditor.h"
1.30 +#include "linkablemapobj.h"
1.31 +#include "exports.h"
1.32 +#include "misc.h"
1.33 +#include "mainwindow.h"
1.34 +#include "extrainfodialog.h"
1.35 +#include "settings.h"
1.36 +
1.37 +#include "icons/flag-note.xpm"
1.38 +#include "icons/flag-url.xpm"
1.39 +#include "icons/flag-vymlink.xpm"
1.40 +#include "icons/flag-scrolled-right.xpm"
1.41 +#include "icons/flag-tmpUnscrolled-right.xpm"
1.42 +#include "icons/flag-questionmark.xpm"
1.43 +#include "icons/flag-exclamationmark.xpm"
1.44 +#include "icons/flag-hook-green.xpm"
1.45 +#include "icons/flag-cross-red.xpm"
1.46 +#include "icons/flag-stopsign.xpm"
1.47 +#include "icons/flag-smiley-good.xpm"
1.48 +#include "icons/flag-smiley-sad.xpm"
1.49 +#include "icons/flag-clock.xpm"
1.50 +#include "icons/flag-lamp.xpm"
1.51 +#include "icons/flag-arrow-up.xpm"
1.52 +#include "icons/flag-arrow-down.xpm"
1.53 +#include "icons/flag-thumb-up.xpm"
1.54 +#include "icons/flag-thumb-down.xpm"
1.55 +#include "icons/flag-heart.xpm"
1.56 +#include "icons/flag-flash.xpm"
1.57 +#include "icons/flag-lifebelt.xpm"
1.58 +
1.59 +extern TextEditor *textEditor;
1.60 +extern int statusbarTime;
1.61 +extern Main *mainWindow;
1.62 +extern FlagRowObj *systemFlagsDefault;
1.63 +extern FlagRowObj *standardFlagsDefault;
1.64 +extern MapEditor *clipboardME;
1.65 +
1.66 +extern QAction *actionFileSave;
1.67 +extern QAction *actionEditUndo;
1.68 +extern QAction *actionEditCopy;
1.69 +extern QAction *actionEditCut;
1.70 +extern QAction *actionEditPaste;
1.71 +extern QAction *actionEditMoveUp;
1.72 +extern QAction *actionEditMoveDown;
1.73 +extern QAction *actionEditToggleScroll;
1.74 +extern QAction *actionEditOpenURL;
1.75 +extern QAction *actionEditURL;
1.76 +extern QAction *actionEditHeading2URL;
1.77 +extern QAction *actionEditBugzilla2URL;
1.78 +extern QAction *actionEditOpenVymLink;
1.79 +extern QAction *actionEditVymLink;
1.80 +extern QAction *actionEditDeleteVymLink;
1.81 +extern QAction *actionEditHeading;
1.82 +extern QAction *actionEditDelete;
1.83 +extern QAction *actionEditAddBranch;
1.84 +extern QAction *actionEditAddBranchAbove;
1.85 +extern QAction *actionEditAddBranchBelow;
1.86 +extern QAction *actionEditImportAdd;
1.87 +extern QAction *actionEditImportReplace;
1.88 +extern QAction *actionEditSaveBranch;
1.89 +extern QAction *actionEditSelectFirst;
1.90 +extern QAction *actionEditSelectLast;
1.91 +extern QAction *actionEditLoadImage;
1.92 +extern QAction *actionEditToggleFloatExport;
1.93 +
1.94 +extern QAction* actionFormatPickColor;
1.95 +extern QAction* actionFormatColorBranch;
1.96 +extern QAction* actionFormatColorSubtree;
1.97 +extern QAction *actionFormatLinkColorHint;
1.98 +extern QAction *actionFormatBackColor;
1.99 +extern QAction *actionFormatLinkColor;
1.100 +
1.101 +extern QActionGroup *actionGroupFormatFrameTypes;
1.102 +extern QAction *actionFormatFrameNone;
1.103 +extern QAction *actionFormatFrameRectangle;
1.104 +
1.105 +extern QActionGroup *actionGroupFormatLinkStyles;
1.106 +extern QAction *actionFormatLinkStyleLine;
1.107 +extern QAction *actionFormatLinkStyleParabel;
1.108 +extern QAction *actionFormatLinkStylePolyLine;
1.109 +extern QAction *actionFormatLinkStylePolyParabel;
1.110 +
1.111 +extern QAction *actionViewToggleNoteEditor;
1.112 +
1.113 +extern QAction *actionSettingsAutoedit;
1.114 +extern QAction *actionSettingsAutoselectHeading;
1.115 +extern QAction *actionSettingsAutoselectText;
1.116 +extern QAction *actionSettingsPasteNewHeading;
1.117 +
1.118 +extern QPopupMenu *branchContextMenu;
1.119 +extern QPopupMenu *floatimageContextMenu;
1.120 +extern QPopupMenu *saveImageFormatMenu;
1.121 +extern QPopupMenu *exportImageFormatMenu;
1.122 +extern QPopupMenu *canvasContextMenu;
1.123 +
1.124 +extern Settings settings;
1.125 +
1.126 +
1.127 +///////////////////////////////////////////////////////////////////////
1.128 +///////////////////////////////////////////////////////////////////////
1.129 +MapEditor::MapEditor(
1.130 + QWidget* parent, bool interactive, const char* name, WFlags f) :
1.131 + QCanvasView(parent,name,f)
1.132 +{
1.133 + //cout << "Constructor ME "<<this<<endl;
1.134 +
1.135 + mapCanvas = new QCanvas(1000,800);
1.136 + mapCanvas->setAdvancePeriod(30);
1.137 +
1.138 + setCanvas (mapCanvas);
1.139 +
1.140 + setVScrollBarMode ( QScrollView::AlwaysOn );
1.141 + setHScrollBarMode ( QScrollView::AlwaysOn );
1.142 +
1.143 + // Now create the _global_ system flags _once_:
1.144 + // (Later all OrnamentedObj copy from this
1.145 + // and set their own canvas)
1.146 + if (!systemFlagsDefault)
1.147 + {
1.148 + systemFlagsDefault = new FlagRowObj (mapCanvas);
1.149 + systemFlagsDefault->setVisibility (false);
1.150 + systemFlagsDefault->setName ("systemFlagsDef");
1.151 +
1.152 + FlagObj *fo = new FlagObj (mapCanvas);
1.153 + fo->load(QPixmap(flag_note_xpm));
1.154 + fo->setName("note");
1.155 + fo->setToolTip(tr("Note"));
1.156 + systemFlagsDefault->addFlag (fo); // makes deep copy
1.157 +
1.158 + fo->load(QPixmap(flag_url_xpm));
1.159 + fo->setName("url");
1.160 + fo->setToolTip(tr("WWW Document (external)"));
1.161 + systemFlagsDefault->addFlag (fo);
1.162 +
1.163 + fo->load(QPixmap(flag_vymlink_xpm));
1.164 + fo->setName("vymLink");
1.165 + fo->setToolTip(tr("Link to another vym map"));
1.166 + systemFlagsDefault->addFlag (fo);
1.167 +
1.168 + fo->load(QPixmap(flag_scrolled_right_xpm));
1.169 + fo->setName("scrolledright");
1.170 + fo->setToolTip(tr("subtree is scrolled"));
1.171 + systemFlagsDefault->addFlag (fo);
1.172 +
1.173 + fo->load(QPixmap(flag_tmpUnscrolled_right_xpm));
1.174 + fo->setName("tmpUnscrolledright");
1.175 + fo->setToolTip(tr("subtree is temporary scrolled"));
1.176 + systemFlagsDefault->addFlag (fo);
1.177 + delete (fo);
1.178 + }
1.179 + if (!standardFlagsDefault)
1.180 + {
1.181 + standardFlagsDefault = new FlagRowObj (mapCanvas);
1.182 + standardFlagsDefault->setVisibility (false);
1.183 + standardFlagsDefault->setName ("standardFlagsDef");
1.184 +
1.185 + FlagObj *fo = new FlagObj (mapCanvas);
1.186 + fo->load(QPixmap(flag_exclamationmark_xpm));
1.187 + fo->setName("exclamationmark");
1.188 + fo->setToolTip(tr("Take care!"));
1.189 + standardFlagsDefault->addFlag (fo); // makes deep copy
1.190 +
1.191 + fo->load(QPixmap(flag_questionmark_xpm));
1.192 + fo->setName("questionmark");
1.193 + fo->setToolTip(tr("Really?"));
1.194 + standardFlagsDefault->addFlag (fo);
1.195 +
1.196 + fo->load(QPixmap(flag_hook_green_xpm));
1.197 + fo->setName("hook-green");
1.198 + fo->setToolTip(tr("ok!"));
1.199 + standardFlagsDefault->addFlag (fo);
1.200 +
1.201 + fo->load(QPixmap(flag_cross_red_xpm));
1.202 + fo->setName("cross-red");
1.203 + fo->setToolTip(tr("Not ok!"));
1.204 + standardFlagsDefault->addFlag (fo);
1.205 +
1.206 + fo->load(QPixmap(flag_stopsign_xpm));
1.207 + fo->setName("stopsign");
1.208 + fo->setToolTip(tr("This won't work!"));
1.209 + standardFlagsDefault->addFlag (fo);
1.210 +
1.211 + fo->load(QPixmap(flag_smiley_good_xpm));
1.212 + fo->setName("smiley-good");
1.213 + fo->setToolTip(tr("Good"));
1.214 + standardFlagsDefault->addFlag (fo);
1.215 +
1.216 + fo->load(QPixmap(flag_smiley_sad_xpm));
1.217 + fo->setName("smiley-sad");
1.218 + fo->setToolTip(tr("Bad"));
1.219 + standardFlagsDefault->addFlag (fo);
1.220 +
1.221 + fo->load(QPixmap(flag_clock_xpm));
1.222 + fo->setName("clock");
1.223 + fo->setToolTip(tr("Time critical"));
1.224 + standardFlagsDefault->addFlag (fo);
1.225 +
1.226 + fo->load(QPixmap(flag_lamp_xpm));
1.227 + fo->setName("lamp");
1.228 + fo->setToolTip(tr("Idea!"));
1.229 + standardFlagsDefault->addFlag (fo);
1.230 +
1.231 + fo->load(QPixmap(flag_arrow_up_xpm));
1.232 + fo->setName("arrow-up");
1.233 + fo->setToolTip(tr("Important"));
1.234 + standardFlagsDefault->addFlag (fo);
1.235 +
1.236 + fo->load(QPixmap(flag_arrow_down_xpm));
1.237 + fo->setName("arrow-down");
1.238 + fo->setToolTip(tr("Unimportant"));
1.239 + standardFlagsDefault->addFlag (fo);
1.240 +
1.241 + fo->load(QPixmap(flag_thumb_up_xpm));
1.242 + fo->setName("thumb-up");
1.243 + fo->setToolTip(tr("I like this"));
1.244 + standardFlagsDefault->addFlag (fo);
1.245 +
1.246 + fo->load(QPixmap(flag_thumb_down_xpm));
1.247 + fo->setName("thumb-down");
1.248 + fo->setToolTip(tr("I do not like this"));
1.249 + standardFlagsDefault->addFlag (fo);
1.250 +
1.251 + fo->load(QPixmap(flag_heart_xpm));
1.252 + fo->setName("heart");
1.253 + fo->setToolTip(tr("I just love... "));
1.254 + standardFlagsDefault->addFlag (fo);
1.255 +
1.256 + fo->load(QPixmap(flag_flash_xpm));
1.257 + fo->setName("flash");
1.258 + fo->setToolTip(tr("Dangerous"));
1.259 + standardFlagsDefault->addFlag (fo);
1.260 +
1.261 + fo->load(QPixmap(flag_lifebelt_xpm));
1.262 + fo->setName("lifebelt");
1.263 + fo->setToolTip(tr("This will help"));
1.264 + standardFlagsDefault->addFlag (fo);
1.265 + delete (fo);
1.266 +
1.267 + }
1.268 +
1.269 + mapCenter = new MapCenterObj(mapCanvas);
1.270 + mapCenter->setVisibility (true);
1.271 + mapCenter->setMapEditor (this);
1.272 + mapCenter->setHeading (tr("New Map"));
1.273 +
1.274 + printer=NULL;
1.275 +
1.276 + lineedit = new QLineEdit(this, "lineedit" );
1.277 + connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEditNoSave() ) );
1.278 + lineedit->hide();
1.279 +
1.280 + actColor=black; setColor (actColor);
1.281 + deflinkcolor=QColor (0,0,255);
1.282 + linkcolorhint=DefaultColor;
1.283 + linkstyle=StylePolyParabel;
1.284 + mapCanvas->setBackgroundColor (white);
1.285 +
1.286 + // Create bitmap cursors, patform dependant
1.287 + #if defined(Q_OS_MACX)
1.288 + #include "icons/cursorhandopen16.xpm"
1.289 + #include "icons/cursorcolorpicker16.xpm"
1.290 + QBitmap cb( 16, 16, chandopen, TRUE );
1.291 + QBitmap cm( 16, 16, chandopenmask, TRUE );
1.292 + handOpenCursor=QCursor ( cb, cm );
1.293 + // set hot spot to tip of picker
1.294 + pickColorCursor=QCursor ( cursorcolorpicker_xpm, 1,15 );
1.295 + #else
1.296 + #include "icons/cursorhandopen.xpm"
1.297 + #include "icons/cursorcolorpicker.xpm"
1.298 +
1.299 + QBitmap cb( 32, 32, chandopen, TRUE );
1.300 + QBitmap cm( 32, 32, chandopenmask, TRUE );
1.301 + handOpenCursor=QCursor ( cb, cm );
1.302 + // set hot spot to tip of picker
1.303 + pickColorCursor=QCursor ( cursorcolorpicker_xpm, 5,27 );
1.304 + #endif
1.305 +
1.306 +
1.307 + pickingColor=false;
1.308 +
1.309 + editingBO=NULL;
1.310 + selection=NULL;
1.311 + selectionLast=NULL;
1.312 + movingObj=NULL;
1.313 +
1.314 + mapChanged=false;
1.315 + mapDefault=true;
1.316 + mapUnsaved=false;
1.317 + undoSelection=NULL;
1.318 +
1.319 + zipped=true;
1.320 + filePath="";
1.321 + fileName="unnamed";
1.322 + mapName="";
1.323 +
1.324 + // Initialize find routine
1.325 + itFind=NULL;
1.326 + EOFind=false;
1.327 +
1.328 + printFrame=true;
1.329 + printFooter=true;
1.330 +
1.331 + blockreposition=false;
1.332 + isInteractive=interactive;
1.333 + if (isInteractive)
1.334 + // Create temporary files
1.335 + makeTmpDirs();
1.336 +
1.337 + // Initially set movingCentre
1.338 + updateViewCenter();
1.339 +
1.340 + mapCenter->reposition(); // for positioning heading
1.341 +}
1.342 +
1.343 +MapEditor::~MapEditor()
1.344 +{
1.345 + //cout <<"Destructor MapEditor\n";
1.346 + if (isInteractive) delTmpDirs();
1.347 +
1.348 + // Save Settings
1.349 + //settings.writeEntry( "/vym/mapeditor/editmode/autoselect", );
1.350 +
1.351 +}
1.352 +
1.353 +QColor MapEditor::color()
1.354 +{
1.355 + return actColor;
1.356 +}
1.357 +
1.358 +QColor MapEditor::backgroundColor()
1.359 +{
1.360 + return mapCanvas->backgroundColor();
1.361 +}
1.362 +
1.363 +MapCenterObj* MapEditor::getMapCenter()
1.364 +{
1.365 + return mapCenter;
1.366 +}
1.367 +
1.368 +QCanvas* MapEditor::getCanvas()
1.369 +{
1.370 + return mapCanvas;
1.371 +}
1.372 +
1.373 +void MapEditor::adjustCanvasSize()
1.374 +{
1.375 + // To adjust the canvas to map, viewport size and position, we have to
1.376 + // do some coordinate magic...
1.377 + //
1.378 + // Get rectangle of (scroll-)view.
1.379 + // We want to be in canvas coords, so
1.380 + // we map. Important if view is zoomed...
1.381 + QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(),
1.382 + visibleWidth(), visibleHeight()) );
1.383 +
1.384 + // Now we need the bounding box of view AND map to calc the correct canvas size.
1.385 + // Why? Because if the map itself is moved out of view, the view has to be enlarged
1.386 + // to avoid jumping aroung...
1.387 + QRect map=mapCenter->getTotalBBox();
1.388 +
1.389 + // right edge - left edge
1.390 + int cw= max(map.x() + map.width(), view.x() + view.width()) - min(map.x(), view.x());
1.391 + int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
1.392 +
1.393 +
1.394 + if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) ||
1.395 + !mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight())
1.396 + )
1.397 + {
1.398 + // move the map on canvas (in order to not move it on screen) this is neccessary
1.399 + // a) if topleft corner of canvas is left or above topleft corner of view and also left of
1.400 + // above topleft corner of map. E.g. if map is completly inside view, but it would be possible
1.401 + // to scroll to an empty area of canvas to the left.
1.402 + // b) if topleft corner of map left of or above topleft of canvas
1.403 + int dx=0;
1.404 + int dy=0;
1.405 +
1.406 + if (cw > mapCanvas->width() )
1.407 + {
1.408 + if (map.x()<0) dx=-map.x();
1.409 + }
1.410 + if (cw < mapCanvas->width() )
1.411 + dx=-min (view.x(),map.x());
1.412 + if (ch > mapCanvas->height() )
1.413 + {
1.414 + if (map.y()<0) dy=-map.y();
1.415 + }
1.416 + if (ch < mapCanvas->height() )
1.417 + {
1.418 + dy=-min (view.y(),map.y());
1.419 + }
1.420 + // We really have to resize now. Let's go...
1.421 + mapCanvas->resize (cw,ch);
1.422 + if ( (dx!=0) || (dy!=0) )
1.423 + {
1.424 + mapCenter->moveAllBy(dx,dy);
1.425 + mapCenter->reposition();
1.426 +
1.427 + // scroll the view (in order to not move map on screen)
1.428 + scrollBy (dx,dy);
1.429 + }
1.430 + }
1.431 +}
1.432 +
1.433 +bool MapEditor::blockReposition()
1.434 +{
1.435 + return blockreposition;
1.436 +}
1.437 +
1.438 +void MapEditor::makeTmpDirs()
1.439 +{
1.440 + // Create unique temporary directories
1.441 + char tmpdir[]="/tmp/vym-XXXXXX";
1.442 + bakMapDir=mkdtemp(tmpdir);
1.443 + makeSubDirs(bakMapDir);
1.444 + // FIXME set permissions
1.445 + // and maybe use QT method for portability
1.446 +}
1.447 +
1.448 +void MapEditor::delTmpDirs()
1.449 +{
1.450 + //FIXME delete tmp directory, better use QT methods here:
1.451 + system ( "rm -rf "+ bakMapDir );
1.452 +}
1.453 +
1.454 +
1.455 +void MapEditor::makeSubDirs(const QString &s)
1.456 +{
1.457 + QDir d(s);
1.458 + d.mkdir ("images");
1.459 + d.mkdir ("flags");
1.460 +}
1.461 +
1.462 +
1.463 +QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, SaveMode savemode)
1.464 +{
1.465 + // tmpdir temporary directory to which data will be writte
1.466 + // prefix mapname, which will be appended to images etc.
1.467 + // writeflags Only write flags for "real" save of map, not undo
1.468 + // offset offset of bbox of whole map in canvas.
1.469 + // Needed for XML export
1.470 + // completeMap if false, only vympart will be written, without
1.471 + // mapcenter
1.472 +
1.473 + // Save Header
1.474 + QString ls;
1.475 + switch (linkstyle)
1.476 + {
1.477 + case StyleLine:
1.478 + ls="StyleLine";
1.479 + break;
1.480 + case StyleParabel:
1.481 + ls="StyleParabel";
1.482 + break;
1.483 + case StylePolyLine:
1.484 + ls="StylePolyLine";
1.485 + break;
1.486 + default:
1.487 + ls="StylePolyParabel";
1.488 + break;
1.489 + }
1.490 +
1.491 + QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
1.492 + QString colhint="";
1.493 + if (linkcolorhint==HeadingColor)
1.494 + colhint=attribut("linkColorHint","HeadingColor");
1.495 +
1.496 + QString mapAttr=attribut("version",__VYM_VERSION__);
1.497 + if (savemode==CompleteMap)
1.498 + mapAttr+= attribut("author",mapCenter->getAuthor()) +
1.499 + attribut("comment",mapCenter->getComment()) +
1.500 + attribut("date",mapCenter->getDate()) +
1.501 + attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
1.502 + attribut("linkStyle", ls ) +
1.503 + attribut("linkColor", deflinkcolor.name() ) +
1.504 + colhint;
1.505 + s+=beginElement("vymmap",mapAttr);
1.506 + incIndent();
1.507 +
1.508 + // Find the used flags while traversing the tree
1.509 + standardFlagsDefault->resetUsedCounter();
1.510 +
1.511 + // Build xml recursivly
1.512 + if (savemode==CompleteMap)
1.513 + s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
1.514 + else
1.515 + {
1.516 + if ( undoSelection &&
1.517 + typeid(*undoSelection) == typeid(BranchObj) )
1.518 + s+=((BranchObj*)(undoSelection))->saveToDir(tmpdir,prefix,offset);
1.519 + }
1.520 +
1.521 + // Save local settings
1.522 + s+=settings.getXMLData (destPath);
1.523 +
1.524 + // Save selection
1.525 + if (selection)
1.526 + s+=valueElement("select",selection->getSelectString());
1.527 +
1.528 + decIndent();
1.529 + s+=endElement("vymmap");
1.530 +
1.531 + if (writeflags)
1.532 + standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
1.533 +
1.534 + return s;
1.535 +}
1.536 +
1.537 +void MapEditor::saveState()
1.538 +{
1.539 + saveState (CompleteMap,NULL);
1.540 +}
1.541 +
1.542 +void MapEditor::saveState(const SaveMode &mode, LinkableMapObj *part)
1.543 +{
1.544 + // all binary data is saved in bakMapDir (created in Constructor)
1.545 + // the xml data itself is kept in memory in backupXML
1.546 + //
1.547 + // For faster write/read of data, a part of the map can be
1.548 + // written. Then the undoSelection will mark, which part of the
1.549 + // map should be replaced if an undo is wanted later.
1.550 +
1.551 + if (mode==PartOfMap && part && (typeid(*part) == typeid (BranchObj) ) )
1.552 + {
1.553 + // Writing a vympart only is useful for BranchObj
1.554 + undoSelection=part;
1.555 + backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),PartOfMap);
1.556 + } else
1.557 + {
1.558 + undoSelection=NULL;
1.559 + backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),CompleteMap);
1.560 + }
1.561 +}
1.562 +
1.563 +void MapEditor::finishedLineEditNoSave()
1.564 +{
1.565 + // This is called by finishedLineEdit or any MapEditor method,
1.566 + // which wants to assure, that lineedits finish, before e.g. a branch is
1.567 + // deleted
1.568 +
1.569 + // After calling LineEdit and using the clipboard, the
1.570 + // focus is not any longer on the main widget, we
1.571 + // have to restore it using parentWidget()->setFocus()
1.572 +
1.573 + if (editingBO!=NULL)
1.574 + {
1.575 + editingBO->setHeading(lineedit->text() );
1.576 + editingBO=NULL;
1.577 + lineedit->releaseKeyboard();
1.578 + lineedit->hide();
1.579 + parentWidget()->setFocus();
1.580 + mapCenter->reposition();
1.581 + adjustCanvasSize();
1.582 + ensureSelectionVisible();
1.583 + }
1.584 +}
1.585 +
1.586 +
1.587 +bool MapEditor::isDefault()
1.588 +{
1.589 + return mapDefault;
1.590 +}
1.591 +
1.592 +bool MapEditor::isUnsaved()
1.593 +{
1.594 + return mapUnsaved;
1.595 +}
1.596 +
1.597 +bool MapEditor::hasChanged()
1.598 +{
1.599 + return mapChanged;
1.600 +}
1.601 +
1.602 +void MapEditor::setChanged()
1.603 +{
1.604 + mapChanged=true;
1.605 + mapDefault=false;
1.606 + mapUnsaved=true;
1.607 + actionEditUndo->setEnabled (true);
1.608 + actionFileSave->setEnabled (true);
1.609 + findReset();
1.610 +}
1.611 +
1.612 +void MapEditor::closeMap()
1.613 +{
1.614 + // Finish open lineEdits
1.615 + if (lineedit) finishedLineEditNoSave();
1.616 +
1.617 + // Unselect before disabling the toolbar actions
1.618 + if (selection) selection->unselect();
1.619 + selection=NULL;
1.620 + updateActions();
1.621 +
1.622 + clear();
1.623 + close();
1.624 +}
1.625 +
1.626 +void MapEditor::setFilePath(QString fname)
1.627 +{
1.628 + setFilePath (fname,fname);
1.629 +}
1.630 +
1.631 +void MapEditor::setFilePath(QString fname, QString destname)
1.632 +{
1.633 + filePath=fname;
1.634 + fileName=fname;
1.635 + destPath=destname;
1.636 +
1.637 + // If fname is not an absolute path, complete it
1.638 + filePath=QDir(fname).absPath();
1.639 + fileDir=filePath.left (1+filePath.findRev ("/"));
1.640 +
1.641 + // Set short name, too. Search from behind:
1.642 + int i=fileName.findRev("/");
1.643 + if (i>=0) fileName=fileName.remove (0,i+1);
1.644 +
1.645 + // Forget the .vym (or .xml) for name of map
1.646 + mapName=fileName.left(fileName.findRev(".",-1,true) );
1.647 +}
1.648 +
1.649 +QString MapEditor::getFilePath()
1.650 +{
1.651 + return filePath;
1.652 +}
1.653 +
1.654 +QString MapEditor::getFileName()
1.655 +{
1.656 + return fileName;
1.657 +}
1.658 +
1.659 +QString MapEditor::getMapName()
1.660 +{
1.661 + return mapName;
1.662 +}
1.663 +
1.664 +QString MapEditor::getDestPath()
1.665 +{
1.666 + return destPath;
1.667 +}
1.668 +
1.669 +int MapEditor::load (QString &fname, const LoadMode &lmode)
1.670 +{
1.671 + // Finish open lineEdits
1.672 + if (lineedit) finishedLineEditNoSave();
1.673 +
1.674 + int returnCode=0;
1.675 +
1.676 + if (lmode==NewMap)
1.677 + {
1.678 + if (selection) selection->unselect();
1.679 + selection=NULL;
1.680 + mapCenter->clear();
1.681 + mapCenter->setMapEditor(this);
1.682 + // (map state is set later at end of load...)
1.683 + } else
1.684 + {
1.685 + setChanged();
1.686 + saveState(PartOfMap,selection);
1.687 + }
1.688 +
1.689 +
1.690 + mapBuilderHandler handler;
1.691 + QFile file( fname );
1.692 +
1.693 + // I am paranoid: file should exist anyway
1.694 + // according to check in mainwindow.
1.695 + if (!file.exists() )
1.696 + {
1.697 + QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1.698 + tr("Couldn't open map " +fname)+".");
1.699 + returnCode=1;
1.700 + } else
1.701 + {
1.702 + blockreposition=true;
1.703 + QXmlInputSource source( file);
1.704 + QXmlSimpleReader reader;
1.705 + reader.setContentHandler( &handler );
1.706 + reader.setErrorHandler( &handler );
1.707 + handler.setMapEditor( this );
1.708 + handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1.709 + handler.setLoadMode (lmode);
1.710 + bool ok = reader.parse( source );
1.711 + blockreposition=false;
1.712 + file.close();
1.713 + if ( ok )
1.714 + {
1.715 + mapCenter->reposition();
1.716 + adjustCanvasSize();
1.717 + if (lmode==NewMap)
1.718 + {
1.719 + mapDefault=false;
1.720 + mapChanged=false;
1.721 + mapUnsaved=false;
1.722 + }
1.723 + } else
1.724 + {
1.725 + QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1.726 + tr( handler.errorProtocol() ) );
1.727 + // returnCode=1;
1.728 + // Still return "success": the map maybe at least
1.729 + // partially read by the parser
1.730 + }
1.731 + }
1.732 + updateActions();
1.733 + return returnCode;
1.734 +}
1.735 +
1.736 +int MapEditor::save (const SaveMode &savemode)
1.737 +{
1.738 + // Finish open lineEdits
1.739 + if (lineedit) finishedLineEditNoSave();
1.740 +
1.741 + int returnCode=0;
1.742 +
1.743 + // Create mapName and fileDir
1.744 + makeSubDirs (fileDir);
1.745 + QString fname;
1.746 + if (saveZipped())
1.747 + // save as .xml
1.748 + fname=mapName+".xml";
1.749 + else
1.750 + // use name given by user, even if he chooses .doc
1.751 + fname=fileName;
1.752 +
1.753 +
1.754 + // Check if fname is writeable
1.755 + QFile file( fileDir+fname);
1.756 + if (!file.open( IO_WriteOnly ) )
1.757 + {
1.758 + QMessageBox::critical( 0, tr( "Critical Save Error" ),
1.759 + tr("Couldn't write to ") +fileDir+fname);
1.760 + return 1;
1.761 + }
1.762 + file.close();
1.763 +
1.764 + QString saveFile;
1.765 + saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),savemode);
1.766 +
1.767 + file.setName ( fileDir + fname);
1.768 + if ( !file.open( IO_WriteOnly ) )
1.769 + {
1.770 + // This should neverever happen
1.771 + QMessageBox::critical(0, tr("Critcal save error"),"MapEditor::save() Couldn't open "+file.name());
1.772 + return 1;
1.773 + }
1.774 +
1.775 + // Write it finally, and write in UTF8, no matter what
1.776 + QTextStream ts( &file );
1.777 + ts.setEncoding (QTextStream::UnicodeUTF8);
1.778 + ts << saveFile;
1.779 + file.close();
1.780 +
1.781 + if (returnCode==0)
1.782 + {
1.783 + mapChanged=false;
1.784 + mapUnsaved=false;
1.785 + actionFileSave->setEnabled(false);
1.786 + }
1.787 +
1.788 + return returnCode;
1.789 +}
1.790 +
1.791 +void MapEditor::setZipped (bool z)
1.792 +{
1.793 + zipped=z;
1.794 +}
1.795 +
1.796 +bool MapEditor::saveZipped ()
1.797 +{
1.798 + return zipped;
1.799 +}
1.800 +
1.801 +void MapEditor::print()
1.802 +{
1.803 + // Finish open lineEdits
1.804 + if (lineedit) finishedLineEditNoSave();
1.805 +
1.806 + if ( !printer )
1.807 + {
1.808 + printer = new QPrinter;
1.809 + printer->setColorMode (QPrinter::Color);
1.810 + }
1.811 +
1.812 + QRect totalBBox=mapCenter->getTotalBBox();
1.813 +
1.814 + // Try to set orientation automagically
1.815 + // Note: Interpretation of generated postscript is amibiguous, if
1.816 + // there are problems with landscape mode, see
1.817 + // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1.818 +
1.819 + if (totalBBox.width()>totalBBox.height())
1.820 + // recommend landscape
1.821 + printer->setOrientation (QPrinter::Landscape);
1.822 + else
1.823 + // recommend portrait
1.824 + printer->setOrientation (QPrinter::Portrait);
1.825 +
1.826 + if ( printer->setup(this) )
1.827 + // returns false, if printing is canceled
1.828 + {
1.829 + QPainter pp(printer);
1.830 +
1.831 + // Don't print the visualisation of selection
1.832 + LinkableMapObj *oldselection=NULL;
1.833 + if (selection)
1.834 + {
1.835 + oldselection=selection;
1.836 + selection->unselect();
1.837 + }
1.838 +
1.839 + // Handle sizes of map and paper:
1.840 + //
1.841 + // setWindow defines which part of the canvas will be transformed
1.842 + // setViewport defines area on paper in device coordinates (dpi)
1.843 + // e.g. (0,50,700,700) is upper part on A4
1.844 + // see also /usr/lib/qt3/doc/html/coordsys.html
1.845 +
1.846 + QPaintDeviceMetrics metrics (printer);
1.847 +
1.848 + double paperAspect = (double)metrics.width() / (double)metrics.height();
1.849 + double mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
1.850 +
1.851 + QRect mapRect=mapCenter->getTotalBBox();
1.852 + QCanvasRectangle *frame=NULL;
1.853 + QCanvasText *footerFN=NULL;
1.854 + QCanvasText *footerDate=NULL;
1.855 + if (printFrame || printFooter)
1.856 + {
1.857 +
1.858 + if (printFrame)
1.859 + {
1.860 + // Print frame around map
1.861 + mapRect.setRect (mapRect.x()-10, mapRect.y()-10,
1.862 + mapRect.width()+20, mapRect.height()+20);
1.863 + frame=new QCanvasRectangle (mapRect,mapCanvas);
1.864 + frame->setBrush (QColor(white));
1.865 + frame->setPen (QColor(black));
1.866 + frame->setZ(0);
1.867 + frame->show();
1.868 + }
1.869 + if (printFooter)
1.870 + {
1.871 + // Print footer below map
1.872 + QFont font;
1.873 + font.setPointSize(10);
1.874 + footerFN=new QCanvasText (mapCanvas);
1.875 + footerFN->setText ("VYM - " + fileName);
1.876 + footerFN->setFont(font);
1.877 + footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
1.878 + footerFN->setZ(Z_TEXT);
1.879 + footerFN->show();
1.880 + footerDate=new QCanvasText (mapCanvas);
1.881 + footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
1.882 + footerDate->setFont(font);
1.883 + footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
1.884 + footerDate->setZ(Z_TEXT);
1.885 + footerDate->show();
1.886 + mapRect.setRect (mapRect.x(), mapRect.y(),
1.887 + mapRect.width(), mapRect.height()+20);
1.888 + }
1.889 + pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height());
1.890 + } else
1.891 + {
1.892 + pp.setWindow (mapRect);
1.893 + }
1.894 +
1.895 + if (mapAspect>=paperAspect)
1.896 + {
1.897 + // Fit horizontally to paper width
1.898 + pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );
1.899 + } else
1.900 + {
1.901 + // Fit vertically to paper height
1.902 + pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());
1.903 + }
1.904 +
1.905 + mapCanvas->drawArea(mapRect, &pp); // draw Canvas to printer
1.906 +
1.907 + // Delete Frame and footer
1.908 + if (footerFN)
1.909 + {
1.910 + delete (footerFN);
1.911 + delete (footerDate);
1.912 + }
1.913 + if (frame) delete (frame);
1.914 +
1.915 + // Restore selection
1.916 + if (oldselection)
1.917 + {
1.918 + selection=oldselection;
1.919 + selection->select();
1.920 + }
1.921 + }
1.922 +}
1.923 +
1.924 +QPixmap MapEditor::getPixmap()
1.925 +{
1.926 + QRect mapRect=mapCenter->getTotalBBox();
1.927 + QPixmap pix (mapRect.size());
1.928 + QPainter pp (&pix);
1.929 +
1.930 + // Don't print the visualisation of selection
1.931 + LinkableMapObj *oldselection=NULL;
1.932 + if (selection)
1.933 + {
1.934 + oldselection=selection;
1.935 + selection->unselect();
1.936 + }
1.937 +
1.938 + pp.setWindow (mapRect);
1.939 +
1.940 + mapCanvas->drawArea(mapRect, &pp); // draw Canvas to painter
1.941 +
1.942 +
1.943 + // Restore selection
1.944 + if (oldselection)
1.945 + {
1.946 + selection=oldselection;
1.947 + selection->select();
1.948 + }
1.949 +
1.950 + return pix;
1.951 +}
1.952 +
1.953 +void MapEditor::exportImage(QString fn)
1.954 +{
1.955 + // Finish open lineEdits
1.956 + if (lineedit) finishedLineEditNoSave();
1.957 +
1.958 + QPixmap pix (getPixmap());
1.959 + pix.save(fn, "PNG");
1.960 +}
1.961 +
1.962 +void MapEditor::exportImage(QString fn, int item)
1.963 +{
1.964 + // Finish open lineEdits
1.965 + if (lineedit) finishedLineEditNoSave();
1.966 +
1.967 + QPixmap pix (getPixmap());
1.968 + pix.save(fn, exportImageFormatMenu->text(item) );
1.969 +}
1.970 +
1.971 +void MapEditor::exportASCII()
1.972 +{
1.973 + // FIXME still experimental
1.974 + QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (ASCII)"));
1.975 + fd->addFilter ("TXT (*.txt)");
1.976 + fd->setCaption("VYM - Export (ASCII) (still experimental)");
1.977 + fd->setMode( QFileDialog::AnyFile );
1.978 + fd->show();
1.979 +
1.980 + if ( fd->exec() == QDialog::Accepted )
1.981 + {
1.982 + if (QFile (fd->selectedFile()).exists() )
1.983 + {
1.984 + QMessageBox mb( "VYM",
1.985 + tr("The file ") + fd->selectedFile() +
1.986 + tr(" exists already. Do you want to overwrite it?"),
1.987 + QMessageBox::Warning,
1.988 + QMessageBox::Yes | QMessageBox::Default,
1.989 + QMessageBox::Cancel | QMessageBox::Escape,
1.990 + QMessageBox::NoButton );
1.991 +
1.992 + mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
1.993 + mb.setButtonText( QMessageBox::No, tr("Cancel"));
1.994 + Export ex;
1.995 + switch( mb.exec() )
1.996 + {
1.997 + case QMessageBox::Yes:
1.998 + // save
1.999 + if (!ex.setOutputDir ("out"))
1.1000 + {
1.1001 + QMessageBox::critical (0,tr("Critical Export Error "),tr("Couldn't create directory ") + "out");
1.1002 + return;
1.1003 + }
1.1004 + break;;
1.1005 + case QMessageBox::Cancel:
1.1006 + // do nothing
1.1007 + return;
1.1008 + break;
1.1009 + }
1.1010 + }
1.1011 + Export ex;
1.1012 + ex.setPath (fd->selectedFile() );
1.1013 + ex.setMapCenter(mapCenter);
1.1014 + ex.exportMap();
1.1015 + }
1.1016 +}
1.1017 +
1.1018 +
1.1019 +void MapEditor::exportXML(const QString &dir)
1.1020 +{
1.1021 + // Create subdirectories
1.1022 + makeSubDirs (dir);
1.1023 +
1.1024 + // write to directory
1.1025 + QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,CompleteMap);
1.1026 + QFile file;
1.1027 +
1.1028 + file.setName ( dir + "/"+mapName+".xml");
1.1029 + if ( !file.open( IO_WriteOnly ) )
1.1030 + {
1.1031 + // This should neverever happen
1.1032 + QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open ")+file.name());
1.1033 + return;
1.1034 + }
1.1035 +
1.1036 + // Write it finally, and write in UTF8, no matter what
1.1037 + QTextStream ts( &file );
1.1038 + ts.setEncoding (QTextStream::UnicodeUTF8);
1.1039 + ts << saveFile;
1.1040 + file.close();
1.1041 +
1.1042 + // Now write image, too
1.1043 + exportImage (dir+"/images/"+mapName+".png");
1.1044 +}
1.1045 +
1.1046 +void MapEditor::clear()
1.1047 +{
1.1048 + if (selection)
1.1049 + {
1.1050 + selection->unselect();
1.1051 + selection=NULL;
1.1052 + }
1.1053 +
1.1054 + mapCenter->clear();
1.1055 +}
1.1056 +
1.1057 +void MapEditor::undo()
1.1058 +{
1.1059 + QDir d;
1.1060 + d.setPath(bakMapDir);
1.1061 + if (d.exists() )
1.1062 + {
1.1063 + // Finish open lineEdits
1.1064 + if (lineedit) finishedLineEditNoSave();
1.1065 +
1.1066 + if (selection)
1.1067 + {
1.1068 + selection->unselect();
1.1069 + selection=NULL;
1.1070 + }
1.1071 +
1.1072 + mapBuilderHandler handler;
1.1073 + QXmlInputSource source;
1.1074 + source.setData(backupXML);
1.1075 + QXmlSimpleReader reader;
1.1076 + reader.setContentHandler( &handler );
1.1077 + reader.setErrorHandler( &handler );
1.1078 + handler.setMapEditor( this );
1.1079 + handler.setTmpDir ( bakMapDir ); // needed to load files with rel. path
1.1080 + if (undoSelection)
1.1081 + {
1.1082 + selection=undoSelection;
1.1083 + selection->select();
1.1084 + handler.setLoadMode (ImportReplace);
1.1085 +
1.1086 + } else
1.1087 + {
1.1088 + mapCenter->clear();
1.1089 + handler.setLoadMode (NewMap);
1.1090 + }
1.1091 + blockreposition=true;
1.1092 + bool ok = reader.parse( source );
1.1093 + blockreposition=false;
1.1094 + if ( ok )
1.1095 + mapCenter->reposition();
1.1096 +
1.1097 + else
1.1098 + {
1.1099 + // This should never ever happen
1.1100 + QMessageBox::critical( 0, tr( "Critical Parse Error by reading backupFile" ),
1.1101 + tr( handler.errorProtocol() )+" in "+backupXML );
1.1102 + }
1.1103 + // Undo not longer available now
1.1104 + actionEditUndo->setEnabled (false);
1.1105 + undoSelection=false;
1.1106 + mapChanged=false;
1.1107 + return;
1.1108 + } else
1.1109 + {
1.1110 + QMessageBox::critical( 0, tr( "Critical Error" ),
1.1111 + "Temporary directory " +bakMapDir +
1.1112 + tr (" used for undo is gone. \n"
1.1113 + "I will create a new one, but at the moment no undo is available.\n"
1.1114 + "Maybe you want to reload your original data.\n\n"
1.1115 + "Sorry for any inconveniences.") );
1.1116 + makeTmpDirs();
1.1117 + }
1.1118 +}
1.1119 +
1.1120 +void MapEditor::copy()
1.1121 +{
1.1122 + // Finish open lineEdits
1.1123 + if (lineedit) finishedLineEditNoSave();
1.1124 +
1.1125 + if (selection)
1.1126 + {
1.1127 + if (typeid(*selection) == typeid(BranchObj) )
1.1128 + {
1.1129 + BranchObj* to;
1.1130 + BranchObj* from;
1.1131 + clipboardME->clear();
1.1132 + clipboardME->getMapCenter()->addBranch();
1.1133 + to=clipboardME->getMapCenter()->getLastBranch();
1.1134 + if (to)
1.1135 + {
1.1136 + from=(BranchObj*)(selection);
1.1137 + to->copy(from);
1.1138 +
1.1139 + // keep position relative to parent
1.1140 + to->move2RelPos ( from->getRelPos());
1.1141 +
1.1142 + // select data in clipboard
1.1143 + clipboardME->select ("bo:0");
1.1144 +
1.1145 + // repositioning makes testing nicer,
1.1146 + // but is not needed usually:
1.1147 + if (clipboardME->isVisible())
1.1148 + {
1.1149 + clipboardME->getMapCenter()->reposition();
1.1150 + }
1.1151 + else
1.1152 + clipboardME->hide();
1.1153 + }
1.1154 + }
1.1155 + if (typeid(*selection) == typeid(FloatImageObj) )
1.1156 + {
1.1157 + FloatImageObj* to;
1.1158 + FloatImageObj* from;
1.1159 + clipboardME->clear();
1.1160 + clipboardME->getMapCenter()->addFloatImage();
1.1161 + to=clipboardME->getMapCenter()->getLastFloatImage();
1.1162 + if (to)
1.1163 + {
1.1164 + from=(FloatImageObj*)(selection);
1.1165 + to->copy(from);
1.1166 +
1.1167 + // select data in clipboard
1.1168 + clipboardME->select ("fi:0");
1.1169 +
1.1170 + // repositioning makes testing nicer,
1.1171 + // but is not needed usually:
1.1172 + if (clipboardME->isVisible())
1.1173 + {
1.1174 + clipboardME->getMapCenter()->reposition();
1.1175 + }
1.1176 + else
1.1177 + clipboardME->hide();
1.1178 + }
1.1179 + }
1.1180 + }
1.1181 +}
1.1182 +
1.1183 +LinkableMapObj* MapEditor::pasteNoSave()
1.1184 +{
1.1185 + return pasteAtNoSave (-1);
1.1186 +}
1.1187 +
1.1188 +LinkableMapObj* MapEditor::pasteAtNoSave(int pos)
1.1189 +{
1.1190 + // Finish open lineEdits
1.1191 + if (lineedit) finishedLineEditNoSave();
1.1192 +
1.1193 + LinkableMapObj *fromLMO=clipboardME->getSelection();
1.1194 + LinkableMapObj *returnLMO=NULL;
1.1195 +
1.1196 + if (selection && fromLMO)
1.1197 + {
1.1198 +
1.1199 + if (typeid(*fromLMO) == typeid(BranchObj) )
1.1200 + {
1.1201 + if (typeid(*selection) == typeid(MapCenterObj))
1.1202 + {
1.1203 + returnLMO=mapCenter->addBranch( (BranchObj*)(fromLMO) );
1.1204 + ((BranchObj*)(returnLMO))->move2RelPos(normalise(fromLMO->getRelPos() ) );
1.1205 + }
1.1206 + if (typeid(*selection) == typeid(BranchObj))
1.1207 + if (pos<0)
1.1208 + returnLMO=((BranchObj*)(selection))->addBranch((BranchObj*)(fromLMO) );
1.1209 + else
1.1210 + {
1.1211 + BranchObj *par=(BranchObj*)(selection->getParObj());
1.1212 + if (par) returnLMO=par->insertBranch((BranchObj*)(fromLMO),pos );
1.1213 + }
1.1214 + }
1.1215 +
1.1216 + if (typeid(*fromLMO) == typeid(FloatImageObj) &&
1.1217 + (typeid(*selection) == typeid (BranchObj) ||
1.1218 + typeid(*selection)==typeid(MapCenterObj)) )
1.1219 + returnLMO=((BranchObj*) (selection))->addFloatImage ((FloatImageObj*)(fromLMO));
1.1220 +
1.1221 + }
1.1222 + return returnLMO;
1.1223 +}
1.1224 +
1.1225 +void MapEditor::cutNoSave()
1.1226 +{
1.1227 + // Finish open lineEdits
1.1228 + if (lineedit) finishedLineEditNoSave();
1.1229 +
1.1230 + BranchObj* bo;
1.1231 + BranchObj* par;
1.1232 + if (selection != NULL) {
1.1233 + if (typeid(*selection) == typeid(BranchObj) )
1.1234 + {
1.1235 + bo=(BranchObj*)(selection);
1.1236 + par=(BranchObj*)(bo->getParObj());
1.1237 + bo->unselect();
1.1238 + selection=NULL;
1.1239 + par->removeBranch(bo);
1.1240 + selection=par;
1.1241 + selection->select();
1.1242 + }
1.1243 + if (typeid(*selection) == typeid(FloatImageObj) )
1.1244 + {
1.1245 + FloatImageObj* fio=(FloatImageObj*)(selection);
1.1246 + par=(BranchObj*)(fio->getParObj());
1.1247 + fio->unselect();
1.1248 + selection=NULL;
1.1249 + par->removeFloatImage(fio);
1.1250 + selection=par;
1.1251 + selection->select();
1.1252 + }
1.1253 + }
1.1254 +}
1.1255 +
1.1256 +void MapEditor::paste()
1.1257 +{
1.1258 + setChanged();
1.1259 + saveState(PartOfMap,selection);
1.1260 + pasteNoSave();
1.1261 + mapCenter->reposition();
1.1262 + adjustCanvasSize();
1.1263 +}
1.1264 +
1.1265 +void MapEditor::cut()
1.1266 +{
1.1267 + setChanged();
1.1268 + saveState(PartOfMap,selection->getParObj());
1.1269 + copy();
1.1270 + cutNoSave();
1.1271 + mapCenter->reposition();
1.1272 + adjustCanvasSize();
1.1273 +}
1.1274 +
1.1275 +void MapEditor::moveBranchUp()
1.1276 +{
1.1277 + // Finish open lineEdits
1.1278 + if (lineedit) finishedLineEditNoSave();
1.1279 +
1.1280 + BranchObj* bo;
1.1281 + BranchObj* par;
1.1282 + if (typeid(*selection) == typeid(BranchObj) )
1.1283 + {
1.1284 + setChanged();
1.1285 + saveState(PartOfMap,selection->getParObj());
1.1286 + bo=(BranchObj*)(selection);
1.1287 + par=(BranchObj*)(bo->getParObj());
1.1288 + selection->unselect();
1.1289 + selection=par->moveBranchUp (bo);
1.1290 + selection->select();
1.1291 + mapCenter->reposition();
1.1292 + ensureSelectionVisible();
1.1293 + }
1.1294 +}
1.1295 +
1.1296 +void MapEditor::moveBranchDown()
1.1297 +{
1.1298 + // Finish open lineEdits
1.1299 + if (lineedit) finishedLineEditNoSave();
1.1300 +
1.1301 + BranchObj* bo;
1.1302 + BranchObj* par;
1.1303 + if (typeid(*selection) == typeid(BranchObj) )
1.1304 + {
1.1305 + setChanged();
1.1306 + saveState(PartOfMap,selection->getParObj());
1.1307 + bo=(BranchObj*)(selection);
1.1308 + par=(BranchObj*)(bo->getParObj());
1.1309 + selection->unselect();
1.1310 + selection=par->moveBranchDown(bo);
1.1311 + selection->select();
1.1312 + mapCenter->reposition();
1.1313 + ensureSelectionVisible();
1.1314 + }
1.1315 +}
1.1316 +
1.1317 +void MapEditor::editHeading()
1.1318 +{
1.1319 + // Finish open lineEdits
1.1320 + if (lineedit) finishedLineEditNoSave();
1.1321 +
1.1322 + if (selection &&
1.1323 + (typeid(*selection) == typeid(BranchObj) ||
1.1324 + typeid(*selection) == typeid(MapCenterObj) ) )
1.1325 + {
1.1326 + setChanged();
1.1327 + saveState(PartOfMap,selection);
1.1328 +
1.1329 + ensureSelectionVisible();
1.1330 + BranchObj *bo=(BranchObj*)(selection);
1.1331 + editingBO=(BranchObj*)(selection);
1.1332 + QPoint p = worldMatrix().map(QPoint (bo->x(),bo->y()));
1.1333 + lineedit->setGeometry(p.x()-contentsX(),p.y()-contentsY(),200,25);
1.1334 + QString s=bo->getHeading();
1.1335 + lineedit->setText(s);
1.1336 + lineedit->setCursorPosition(1);
1.1337 + if (actionSettingsAutoselectText->isOn() && !s.isEmpty() && actionSettingsPasteNewHeading->isOn() )
1.1338 + lineedit->selectAll();
1.1339 + lineedit->show();
1.1340 +
1.1341 + lineedit->grabKeyboard();
1.1342 + lineedit->setFocus();
1.1343 + }
1.1344 +}
1.1345 +
1.1346 +
1.1347 +void MapEditor::addNewBranch(int pos)
1.1348 +{
1.1349 + // Finish open lineEdits
1.1350 + if (lineedit) finishedLineEditNoSave();
1.1351 +
1.1352 + if (selection &&
1.1353 + (typeid(*selection) == typeid(BranchObj) ||
1.1354 + typeid(*selection) == typeid(MapCenterObj) ) )
1.1355 + {
1.1356 + setChanged();
1.1357 + saveState(PartOfMap,selection);
1.1358 +
1.1359 + BranchObj* bo1 = (BranchObj*) (selection);
1.1360 + bool wasScrolled=false;
1.1361 + BranchObj *newbo=NULL;
1.1362 + if (pos==0)
1.1363 + {
1.1364 + // save scroll state. If scrolled, automatically select
1.1365 + // new branch in order to tmp unscroll parent...
1.1366 + wasScrolled=bo1->isScrolled();
1.1367 + newbo=bo1->addBranch();
1.1368 + } else
1.1369 + {
1.1370 + BranchObj *parbo=(BranchObj*)(selection->getParObj());
1.1371 + if (parbo)
1.1372 + {
1.1373 + if (pos<0)
1.1374 + // add above selection
1.1375 + newbo=parbo->insertBranch(bo1->getNum());
1.1376 + else
1.1377 + // add below selection
1.1378 + newbo=parbo->insertBranch(bo1->getNum()+1);
1.1379 + } else
1.1380 + // This should not happen...
1.1381 + return;
1.1382 +
1.1383 + }
1.1384 +
1.1385 + LinkableMapObj *oldselection=selection;
1.1386 +
1.1387 + mapCenter->reposition();
1.1388 + adjustCanvasSize();
1.1389 + if (actionSettingsAutoedit->isOn() ||
1.1390 + actionSettingsAutoselectHeading->isOn() )
1.1391 + {
1.1392 + selection->unselect();
1.1393 + selection=newbo;
1.1394 + selection->select();
1.1395 + if (actionSettingsPasteNewHeading->isOn() )
1.1396 + {
1.1397 + BranchObj *bo2= (BranchObj*)(selection);
1.1398 + bo2->setHeading("");
1.1399 + }
1.1400 + if (actionSettingsAutoedit->isOn() )
1.1401 + editHeading();
1.1402 + if (!actionSettingsAutoselectHeading->isOn()
1.1403 + && !wasScrolled)
1.1404 + {
1.1405 + selection->unselect();
1.1406 + selection=oldselection;
1.1407 + selection->select();
1.1408 + }
1.1409 + }
1.1410 + }
1.1411 +}
1.1412 +
1.1413 +void MapEditor::deleteSelection()
1.1414 +{
1.1415 + // Finish open lineEdits
1.1416 + if (lineedit) finishedLineEditNoSave();
1.1417 +
1.1418 + if (selection && typeid(*selection) ==typeid(BranchObj) )
1.1419 + {
1.1420 + setChanged();
1.1421 + saveState(PartOfMap,selection->getParObj());
1.1422 + BranchObj* bo=dynamic_cast <BranchObj*> (selection);
1.1423 + BranchObj* par=(BranchObj*)(bo->getParObj());
1.1424 + bo->unselect();
1.1425 + selection=NULL;
1.1426 + par->removeBranch(bo);
1.1427 + selection=par;
1.1428 + selection->select();
1.1429 + ensureSelectionVisible();
1.1430 + mapCenter->reposition();
1.1431 + adjustCanvasSize();
1.1432 + }
1.1433 + if (selection && typeid(*selection) ==typeid(FloatImageObj) )
1.1434 + {
1.1435 + setChanged();
1.1436 + saveState(PartOfMap,selection->getParObj());
1.1437 + FloatImageObj* fio=dynamic_cast <FloatImageObj*> (selection);
1.1438 + BranchObj* par=(BranchObj*)(fio->getParObj());
1.1439 + fio->unselect();
1.1440 + selection=NULL;
1.1441 + par->removeFloatImage(fio);
1.1442 + selection=par;
1.1443 + selection->select();
1.1444 + ensureSelectionVisible();
1.1445 + mapCenter->reposition();
1.1446 + adjustCanvasSize();
1.1447 + }
1.1448 +}
1.1449 +
1.1450 +LinkableMapObj* MapEditor::getSelection()
1.1451 +{
1.1452 + return selection;
1.1453 +}
1.1454 +
1.1455 +bool MapEditor::select (QString s)
1.1456 +{
1.1457 + LinkableMapObj *lmo=mapCenter;
1.1458 + QString part;
1.1459 + QString typ;
1.1460 + QString num;
1.1461 + while (!s.isEmpty() )
1.1462 + {
1.1463 + part=s.section(",",0,0);
1.1464 + typ=part.left (3);
1.1465 + num=part.right(part.length() - 3);
1.1466 +
1.1467 + if (typ=="mc:")
1.1468 + {
1.1469 + if (num=="")
1.1470 + break;
1.1471 + else
1.1472 + lmo=mapCenter->getBranchNum (num.toUInt());
1.1473 + } else
1.1474 + if (typ=="bo:")
1.1475 + lmo=((BranchObj*)(lmo))->getBranchNum (num.toUInt());
1.1476 + else
1.1477 + if (typ=="fi:")
1.1478 + lmo=((BranchObj*)(lmo))->getFloatImageNum (num.toUInt());
1.1479 +
1.1480 +
1.1481 +
1.1482 + if (!lmo) break;
1.1483 +
1.1484 + if (s.contains(","))
1.1485 + s=s.right(s.length() - part.length() -1 );
1.1486 + else
1.1487 + break;
1.1488 + }
1.1489 +
1.1490 + // Finally select the found object
1.1491 + if (lmo)
1.1492 + {
1.1493 + if (selection) selection->unselect();
1.1494 + selection=lmo;
1.1495 + selection->select();
1.1496 + adjustCanvasSize();
1.1497 + ensureSelectionVisible();
1.1498 + return true;
1.1499 + } else
1.1500 + return false;
1.1501 +
1.1502 +
1.1503 +}
1.1504 +
1.1505 +void MapEditor::unselect()
1.1506 +{
1.1507 + if (selection)
1.1508 + {
1.1509 + selectionLast=selection;
1.1510 + selection->unselect();
1.1511 + selection=NULL;
1.1512 + }
1.1513 +}
1.1514 +
1.1515 +void MapEditor::reselect()
1.1516 +{
1.1517 + if (selectionLast)
1.1518 + {
1.1519 + selection=selectionLast;
1.1520 + selection->select();
1.1521 + selectionLast=NULL;
1.1522 + }
1.1523 +}
1.1524 +
1.1525 +void MapEditor::selectNextBranch()
1.1526 +{
1.1527 + // Increase number of branch
1.1528 + if (selection)
1.1529 + {
1.1530 + QString s=selection->getSelectString();
1.1531 + QString part;
1.1532 + QString typ;
1.1533 + QString num;
1.1534 +
1.1535 + // Where am I?
1.1536 + part=s.section(",",-1);
1.1537 + typ=part.left (3);
1.1538 + num=part.right(part.length() - 3);
1.1539 +
1.1540 + s=s.left (s.length() -num.length());
1.1541 +
1.1542 + // Go to next lmo
1.1543 + num=QString ("%1").arg(num.toUInt()+1);
1.1544 +
1.1545 + s=s+num;
1.1546 +
1.1547 + // Try to select this one
1.1548 + if (select (s)) return;
1.1549 +
1.1550 + // We have no direct successor,
1.1551 + // try to increase the parental number in order to
1.1552 + // find a successor with same depth
1.1553 +
1.1554 + int d=selection->getDepth();
1.1555 + int oldDepth=d;
1.1556 + int i;
1.1557 + bool found=false;
1.1558 + bool b;
1.1559 + while (!found && d>0)
1.1560 + {
1.1561 + s=s.section (",",0,d-1);
1.1562 + // replace substring of current depth in s with "1"
1.1563 + part=s.section(",",-1);
1.1564 + typ=part.left (3);
1.1565 + num=part.right(part.length() - 3);
1.1566 +
1.1567 + if (d>1)
1.1568 + {
1.1569 + // increase number of parent
1.1570 + num=QString ("%1").arg(num.toUInt()+1);
1.1571 + s=s.section (",",0,d-2) + ","+ typ+num;
1.1572 + } else
1.1573 + {
1.1574 + // Special case, look at orientation
1.1575 + if (selection->getOrientation()==OrientRightOfCenter)
1.1576 + num=QString ("%1").arg(num.toUInt()+1);
1.1577 + else
1.1578 + num=QString ("%1").arg(num.toUInt()-1);
1.1579 + s=typ+num;
1.1580 + }
1.1581 +
1.1582 + if (select (s))
1.1583 + // pad to oldDepth, select the first branch for each depth
1.1584 + for (i=d;i<oldDepth;i++)
1.1585 + {
1.1586 + b=select (s);
1.1587 + if (b)
1.1588 + {
1.1589 + if ( ((BranchObj*)(selection))->countBranches()>0)
1.1590 + s+=",bo:0";
1.1591 + else
1.1592 + break;
1.1593 + } else
1.1594 + break;
1.1595 + }
1.1596 +
1.1597 + // try to select the freshly built string
1.1598 + found=select(s);
1.1599 + d--;
1.1600 + }
1.1601 + return;
1.1602 + }
1.1603 +}
1.1604 +
1.1605 +void MapEditor::selectPrevBranch()
1.1606 +{
1.1607 + // Decrease number of branch
1.1608 + if (selection)
1.1609 + {
1.1610 + QString s=selection->getSelectString();
1.1611 + QString part;
1.1612 + QString typ;
1.1613 + QString num;
1.1614 +
1.1615 + // Where am I?
1.1616 + part=s.section(",",-1);
1.1617 + typ=part.left (3);
1.1618 + num=part.right(part.length() - 3);
1.1619 +
1.1620 + s=s.left (s.length() -num.length());
1.1621 +
1.1622 + // Go to next lmo
1.1623 + num=QString ("%1").arg(num.toUInt()-1);
1.1624 +
1.1625 + s=s+num;
1.1626 +
1.1627 + // Try to select this one
1.1628 + if (select (s)) return;
1.1629 +
1.1630 + // We have no direct precessor,
1.1631 + // try to decrease the parental number in order to
1.1632 + // find a precessor with same depth
1.1633 +
1.1634 + int d=selection->getDepth();
1.1635 + int oldDepth=d;
1.1636 + int i;
1.1637 + bool found=false;
1.1638 + bool b;
1.1639 + while (!found && d>0)
1.1640 + {
1.1641 + s=s.section (",",0,d-1);
1.1642 + // replace substring of current depth in s with "1"
1.1643 + part=s.section(",",-1);
1.1644 + typ=part.left (3);
1.1645 + num=part.right(part.length() - 3);
1.1646 +
1.1647 + if (d>1)
1.1648 + {
1.1649 + // decrease number of parent
1.1650 + num=QString ("%1").arg(num.toUInt()-1);
1.1651 + s=s.section (",",0,d-2) + ","+ typ+num;
1.1652 + } else
1.1653 + {
1.1654 + // Special case, look at orientation
1.1655 + if (selection->getOrientation()==OrientRightOfCenter)
1.1656 + num=QString ("%1").arg(num.toUInt()-1);
1.1657 + else
1.1658 + num=QString ("%1").arg(num.toUInt()+1);
1.1659 + s=typ+num;
1.1660 + }
1.1661 +
1.1662 + if (select(s))
1.1663 + // pad to oldDepth, select the last branch for each depth
1.1664 + for (i=d;i<oldDepth;i++)
1.1665 + {
1.1666 + b=select (s);
1.1667 + if (b)
1.1668 + if ( ((BranchObj*)(selection))->countBranches()>0)
1.1669 + s+=",bo:"+ QString ("%1").arg( ((BranchObj*)(selection))->countBranches()-1 );
1.1670 + else
1.1671 + break;
1.1672 + else
1.1673 + break;
1.1674 + }
1.1675 +
1.1676 + // try to select the freshly built string
1.1677 + found=select(s);
1.1678 + d--;
1.1679 + }
1.1680 + return;
1.1681 + }
1.1682 +}
1.1683 +
1.1684 +void MapEditor::selectUpperBranch()
1.1685 +{
1.1686 + // Finish open lineEdits
1.1687 + if (lineedit) finishedLineEditNoSave();
1.1688 +
1.1689 + if (selection)
1.1690 + {
1.1691 + if (typeid(*selection) == typeid(BranchObj))
1.1692 + {
1.1693 + if (selection->getOrientation()==OrientRightOfCenter)
1.1694 + selectPrevBranch();
1.1695 + else
1.1696 + if (selection->getDepth()==1)
1.1697 + selectNextBranch();
1.1698 + else
1.1699 + selectPrevBranch();
1.1700 + }
1.1701 + }
1.1702 +}
1.1703 +
1.1704 +void MapEditor::selectLowerBranch()
1.1705 +{
1.1706 + // Finish open lineEdits
1.1707 + if (lineedit) finishedLineEditNoSave();
1.1708 +
1.1709 + if (selection)
1.1710 + {
1.1711 + if (typeid(*selection) == typeid(BranchObj))
1.1712 + {
1.1713 + if (selection->getOrientation()==OrientRightOfCenter)
1.1714 + selectNextBranch();
1.1715 + else
1.1716 + if (selection->getDepth()==1)
1.1717 + selectPrevBranch();
1.1718 + else
1.1719 + selectNextBranch();
1.1720 + }
1.1721 + }
1.1722 +}
1.1723 +
1.1724 +
1.1725 +void MapEditor::selectLeftBranch()
1.1726 +{
1.1727 + // Finish open lineEdits
1.1728 + if (lineedit) finishedLineEditNoSave();
1.1729 +
1.1730 + BranchObj* bo;
1.1731 + BranchObj* par;
1.1732 + if (selection)
1.1733 + {
1.1734 + if (typeid(*selection) == typeid(MapCenterObj))
1.1735 + {
1.1736 + par= (BranchObj*) (selection);
1.1737 + bo=par->getLastSelectedBranch();
1.1738 + if (bo)
1.1739 + {
1.1740 + // Workaround for reselecting on left and right side
1.1741 + if (bo->getOrientation()==OrientRightOfCenter)
1.1742 + {
1.1743 + bo=par->getLastBranch();
1.1744 + }
1.1745 + if (bo)
1.1746 + {
1.1747 + par->unselect();
1.1748 + selection=bo;
1.1749 + selection->select();
1.1750 + adjustCanvasSize();
1.1751 + ensureSelectionVisible();
1.1752 + }
1.1753 + }
1.1754 + } else
1.1755 + {
1.1756 + par=(BranchObj*)(selection->getParObj());
1.1757 + if (selection->getOrientation()==OrientRightOfCenter)
1.1758 + {
1.1759 + if (typeid(*selection) == typeid(BranchObj) ||
1.1760 + typeid(*selection) == typeid(FloatImageObj))
1.1761 + {
1.1762 + selection->unselect();
1.1763 + selection=par;
1.1764 + selection->select();
1.1765 + adjustCanvasSize();
1.1766 + ensureSelectionVisible();
1.1767 + }
1.1768 + } else
1.1769 + {
1.1770 + if (typeid(*selection) == typeid(BranchObj) )
1.1771 + {
1.1772 + bo=((BranchObj*)(selection))->getLastSelectedBranch();
1.1773 + if (bo)
1.1774 + {
1.1775 + selection->unselect();
1.1776 + selection=bo;
1.1777 + selection->select();
1.1778 + adjustCanvasSize();
1.1779 + ensureSelectionVisible();
1.1780 + }
1.1781 + }
1.1782 + }
1.1783 + }
1.1784 + }
1.1785 +}
1.1786 +
1.1787 +void MapEditor::selectRightBranch()
1.1788 +{
1.1789 + // Finish open lineEdits
1.1790 + if (lineedit) finishedLineEditNoSave();
1.1791 +
1.1792 + BranchObj* bo;
1.1793 + BranchObj* par;
1.1794 +
1.1795 + if (selection)
1.1796 + {
1.1797 + if (typeid(*selection) == typeid(MapCenterObj))
1.1798 + {
1.1799 + par= (BranchObj*) (selection);
1.1800 + bo=par->getLastSelectedBranch();
1.1801 + if (bo)
1.1802 + {
1.1803 + // Workaround for relecting on left and right side
1.1804 + if (bo->getOrientation()==OrientLeftOfCenter)
1.1805 + bo=par->getFirstBranch();
1.1806 + if (bo)
1.1807 + {
1.1808 + par->unselect();
1.1809 + selection=bo;
1.1810 + selection->select();
1.1811 + ensureSelectionVisible();
1.1812 + }
1.1813 + }
1.1814 + } else
1.1815 + {
1.1816 + par=(BranchObj*)(selection->getParObj());
1.1817 + if (selection->getOrientation()==OrientLeftOfCenter)
1.1818 + {
1.1819 + if (typeid(*selection) == typeid(BranchObj) ||
1.1820 + typeid(*selection) == typeid(FloatImageObj))
1.1821 + {
1.1822 + selection->unselect();
1.1823 + selection=par;
1.1824 + selection->select();
1.1825 + adjustCanvasSize();
1.1826 + ensureSelectionVisible();
1.1827 + }
1.1828 + } else
1.1829 + {
1.1830 + if (typeid(*selection) == typeid(BranchObj) )
1.1831 + {
1.1832 + bo=((BranchObj*)(selection))->getLastSelectedBranch();
1.1833 + if (bo)
1.1834 + {
1.1835 + selection->unselect();
1.1836 + selection=bo;
1.1837 + selection->select();
1.1838 + adjustCanvasSize();
1.1839 + ensureSelectionVisible();
1.1840 + }
1.1841 + }
1.1842 + }
1.1843 + }
1.1844 + }
1.1845 +}
1.1846 +
1.1847 +void MapEditor::selectFirstBranch()
1.1848 +{
1.1849 + // Finish open lineEdits
1.1850 + if (lineedit) finishedLineEditNoSave();
1.1851 +
1.1852 + BranchObj *bo1;
1.1853 + BranchObj *bo2;
1.1854 + BranchObj* par;
1.1855 + if (selection) {
1.1856 + if (typeid(*selection) == typeid(BranchObj))
1.1857 + {
1.1858 + bo1= (BranchObj*) (selection);
1.1859 + par=(BranchObj*)(bo1->getParObj());
1.1860 + bo2=par->getFirstBranch();
1.1861 + if (bo2) {
1.1862 + bo1->unselect();
1.1863 + selection=bo2;
1.1864 + selection->select();
1.1865 + ensureSelectionVisible();
1.1866 + }
1.1867 + }
1.1868 + adjustCanvasSize();
1.1869 + }
1.1870 +}
1.1871 +
1.1872 +void MapEditor::selectLastBranch()
1.1873 +{
1.1874 + // Finish open lineEdits
1.1875 + if (lineedit) finishedLineEditNoSave();
1.1876 +
1.1877 + BranchObj *bo1;
1.1878 + BranchObj *bo2;
1.1879 + BranchObj* par;
1.1880 + if (selection) {
1.1881 + if (typeid(*selection) == typeid(BranchObj))
1.1882 + {
1.1883 + bo1= (BranchObj*) (selection);
1.1884 + par=(BranchObj*)(bo1->getParObj());
1.1885 + bo2=par->getLastBranch();
1.1886 + if (bo2) {
1.1887 + bo1->unselect();
1.1888 + selection=bo2;
1.1889 + selection->select();
1.1890 + ensureSelectionVisible();
1.1891 + }
1.1892 + }
1.1893 + adjustCanvasSize();
1.1894 + }
1.1895 +}
1.1896 +
1.1897 +void MapEditor::setColor(QColor c)
1.1898 +{
1.1899 + actColor=c;
1.1900 +}
1.1901 +
1.1902 +void MapEditor::selectBackgroundColor()
1.1903 +{
1.1904 + // Finish open lineEdits
1.1905 + if (lineedit) finishedLineEditNoSave();
1.1906 +
1.1907 + QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
1.1908 + if ( !col.isValid() ) return;
1.1909 + setBackgroundColor( col );
1.1910 + setChanged();
1.1911 +}
1.1912 +
1.1913 +void MapEditor::setBackgroundColor(QColor c)
1.1914 +{
1.1915 + mapCanvas->setBackgroundColor (c);
1.1916 +}
1.1917 +
1.1918 +QColor MapEditor::pickColor()
1.1919 +{
1.1920 + if (selection)
1.1921 + {
1.1922 + if (typeid(*selection) == typeid(BranchObj) ||
1.1923 + typeid(*selection) == typeid(MapCenterObj))
1.1924 + {
1.1925 + BranchObj *bo=(BranchObj*)(selection);
1.1926 + actColor=bo->getColor();
1.1927 + }
1.1928 + }
1.1929 + return actColor;
1.1930 +}
1.1931 +
1.1932 +void MapEditor::colorItem()
1.1933 +{
1.1934 + if (selection)
1.1935 + {
1.1936 + if (typeid(*selection) == typeid(BranchObj) ||
1.1937 + typeid(*selection) == typeid(MapCenterObj))
1.1938 + {
1.1939 + setChanged();
1.1940 + saveState(PartOfMap,selection);
1.1941 + BranchObj *bo=(BranchObj*)(selection);
1.1942 + bo->setColor(actColor, false); // color links, color childs
1.1943 + }
1.1944 + }
1.1945 +}
1.1946 +
1.1947 +void MapEditor::colorBranch()
1.1948 +{
1.1949 + if (selection)
1.1950 + {
1.1951 + if (typeid(*selection) == typeid(BranchObj) ||
1.1952 + typeid(*selection) == typeid(MapCenterObj))
1.1953 + {
1.1954 + setChanged();
1.1955 + saveState(PartOfMap,selection);
1.1956 + BranchObj *bo=(BranchObj*)(selection);
1.1957 + bo->setColor(actColor, true); // color links, color childs
1.1958 + }
1.1959 + }
1.1960 +}
1.1961 +
1.1962 +
1.1963 +void MapEditor::toggleStandardFlag(QString f)
1.1964 +{
1.1965 + if (selection)
1.1966 + {
1.1967 + setChanged();
1.1968 + saveState(PartOfMap,selection);
1.1969 + ((BranchObj*)(selection))->toggleStandardFlag (f);
1.1970 + }
1.1971 +}
1.1972 +
1.1973 +void MapEditor::setViewCenter()
1.1974 +{
1.1975 + // transform to CanvasView Coord:
1.1976 + QPoint p=worldMatrix().map(movingCenter);
1.1977 + center ( p.x(), p.y());
1.1978 +}
1.1979 +
1.1980 +
1.1981 +BranchObj* MapEditor::findText (QString s, bool cs)
1.1982 +{
1.1983 + if (!itFind)
1.1984 + { // Nothing found or new find process
1.1985 + if (EOFind)
1.1986 + // nothing found, start again
1.1987 + EOFind=false;
1.1988 + itFind=mapCenter->first();
1.1989 + }
1.1990 + bool searching=true;
1.1991 + bool foundNote=false;
1.1992 + while (searching && !EOFind)
1.1993 + {
1.1994 + if (itFind)
1.1995 + {
1.1996 + // Searching in Note
1.1997 + if (itFind->getNote().contains(s,cs))
1.1998 + {
1.1999 + if (selection!=itFind)
1.2000 + {
1.2001 + if (selection) ((BranchObj*)(selection))->unselect();
1.2002 + selection=itFind;
1.2003 + selection->select();
1.2004 + adjustCanvasSize();
1.2005 + ensureSelectionVisible();
1.2006 + }
1.2007 + if (textEditor->findText(s,cs))
1.2008 + {
1.2009 + searching=false;
1.2010 + foundNote=true;
1.2011 + }
1.2012 + }
1.2013 + // Searching in Heading
1.2014 + if (searching && itFind->getHeading().contains (s,cs) )
1.2015 + {
1.2016 + if (selection) ((BranchObj*)(selection))->unselect();
1.2017 + selection=itFind;
1.2018 + selection->select();
1.2019 + adjustCanvasSize();
1.2020 + ensureSelectionVisible();
1.2021 + searching=false;
1.2022 + }
1.2023 + }
1.2024 + if (!foundNote)
1.2025 + {
1.2026 + itFind=itFind->next();
1.2027 + if (!itFind) EOFind=true;
1.2028 + }
1.2029 + }
1.2030 + if (!searching)
1.2031 + {
1.2032 + adjustCanvasSize();
1.2033 + return (BranchObj*)(selection);
1.2034 + } else
1.2035 + return NULL;
1.2036 +}
1.2037 +
1.2038 +void MapEditor::findReset()
1.2039 +{ // Necessary if text to find changes during a find process
1.2040 + itFind=NULL;
1.2041 + EOFind=false;
1.2042 +}
1.2043 +
1.2044 +void MapEditor::openURL()
1.2045 +{
1.2046 + if (selection )
1.2047 + {
1.2048 + if (typeid(*selection) == typeid(BranchObj) ||
1.2049 + typeid(*selection) == typeid(MapCenterObj))
1.2050 + {
1.2051 + QString url=((BranchObj*)(selection))->getURL();
1.2052 +
1.2053 + QProcess *proc = new QProcess( this );
1.2054 +
1.2055 +#if !defined(Q_OS_MACX)
1.2056 + proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL","konqueror" ));
1.2057 +#else
1.2058 + proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL",
1.2059 + "/Applications/Safari.app/Contents/MacOS/Safari" ));
1.2060 +#endif
1.2061 +
1.2062 + proc->addArgument( url);
1.2063 +
1.2064 + if ( !proc->start() )
1.2065 + // error handling
1.2066 + if (mainWindow->settingsURL() )
1.2067 + openURL();
1.2068 + }
1.2069 + }
1.2070 +}
1.2071 +
1.2072 +void MapEditor::editURL()
1.2073 +{
1.2074 + if (selection && (typeid(*selection) == typeid(BranchObj) ||
1.2075 + typeid(*selection) == typeid(MapCenterObj)) )
1.2076 + {
1.2077 + bool ok;
1.2078 + QString text = QInputDialog::getText(
1.2079 + "VYM", tr("Enter URL:"), QLineEdit::Normal,
1.2080 + ((BranchObj*)(selection))->getURL(), &ok, this );
1.2081 + if ( ok)
1.2082 + {
1.2083 + // user entered something and pressed OK
1.2084 + ((BranchObj*)(selection))->setURL (text);
1.2085 + updateActions();
1.2086 + setChanged();
1.2087 + }
1.2088 + }
1.2089 +}
1.2090 +
1.2091 +void MapEditor::editHeading2URL()
1.2092 +{
1.2093 + if (selection && (typeid(*selection) == typeid(BranchObj) ||
1.2094 + typeid(*selection) == typeid(MapCenterObj)) )
1.2095 + {
1.2096 + BranchObj *b=(BranchObj*)(selection);
1.2097 + b->setURL (b->getHeading());
1.2098 + updateActions();
1.2099 + setChanged();
1.2100 + }
1.2101 +}
1.2102 +
1.2103 +void MapEditor::editBugzilla2URL()
1.2104 +{
1.2105 + if (selection && (typeid(*selection) == typeid(BranchObj) ||
1.2106 + typeid(*selection) == typeid(MapCenterObj)) )
1.2107 + {
1.2108 + BranchObj *b=(BranchObj*)(selection);
1.2109 + b->setURL ("http://bugzilla.suse.de/show_bug.cgi?id="+b->getHeading());
1.2110 + updateActions();
1.2111 + setChanged();
1.2112 + }
1.2113 +}
1.2114 +
1.2115 +void MapEditor::editVymLink()
1.2116 +{
1.2117 + if (selection && (typeid(*selection) == typeid(BranchObj) ||
1.2118 + typeid(*selection) == typeid(MapCenterObj)) )
1.2119 + {
1.2120 + QFileDialog *fd=new QFileDialog( this,tr("VYM - Link to another map"));
1.2121 + fd->addFilter (QString (tr("vym map") + " (*.vym)"));
1.2122 + fd->setCaption(tr("VYM - Link to another map"));
1.2123 + if (! ((BranchObj*)(selection))->getVymLink().isEmpty() )
1.2124 + fd->setSelection( ((BranchObj*)(selection))->getVymLink() );
1.2125 + fd->show();
1.2126 +
1.2127 + QString fn;
1.2128 + if ( fd->exec() == QDialog::Accepted )
1.2129 + ((BranchObj*)(selection))->setVymLink (fd->selectedFile() );
1.2130 + updateActions();
1.2131 + mapCenter->reposition();
1.2132 + adjustCanvasSize();
1.2133 + canvas()->update();
1.2134 + setChanged();
1.2135 + }
1.2136 +}
1.2137 +
1.2138 +void MapEditor::deleteVymLink()
1.2139 +{
1.2140 + if (selection && (typeid(*selection) == typeid(BranchObj) ||
1.2141 + typeid(*selection) == typeid(MapCenterObj)) )
1.2142 + {
1.2143 + ((BranchObj*)(selection))->setVymLink ("" );
1.2144 + updateActions();
1.2145 + mapCenter->reposition();
1.2146 + adjustCanvasSize();
1.2147 + canvas()->update();
1.2148 + setChanged();
1.2149 + }
1.2150 +}
1.2151 +
1.2152 +QString MapEditor::getVymLink()
1.2153 +{
1.2154 + if (selection && (typeid(*selection) == typeid(BranchObj) ||
1.2155 + typeid(*selection) == typeid(MapCenterObj)) )
1.2156 + {
1.2157 + return ((BranchObj*)(selection))->getVymLink();
1.2158 + }
1.2159 + return "";
1.2160 +
1.2161 +}
1.2162 +
1.2163 +void MapEditor::editMapInfo()
1.2164 +{
1.2165 + ExtraInfoDialog dia;
1.2166 + dia.setMapName (getFileName() );
1.2167 + dia.setAuthor (mapCenter->getAuthor() );
1.2168 + dia.setComment(mapCenter->getComment() );
1.2169 +
1.2170 + // Calc some stats
1.2171 + QString stats;
1.2172 + int i=0;
1.2173 + QCanvasItemList l=canvas()->allItems();
1.2174 + for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
1.2175 + i++;
1.2176 + stats+=QString ("%1 items on canvas\n").arg (i,6);
1.2177 +
1.2178 + uint b=0;
1.2179 + uint f=0;
1.2180 + uint n=0;
1.2181 + BranchObj *bo;
1.2182 + bo=mapCenter->first();
1.2183 + while (bo)
1.2184 + {
1.2185 + if (!bo->getNote().isEmpty() ) n++;
1.2186 + f+= bo->countFloatImages();
1.2187 + b++;
1.2188 + bo=bo->next();
1.2189 + }
1.2190 + stats+=QString ("%1 branches\n").arg (b-1,6);
1.2191 + stats+=QString ("%1 notes\n").arg (n,6);
1.2192 + stats+=QString ("%1 images\n").arg (f,6);
1.2193 + dia.setStats (stats);
1.2194 +
1.2195 + // Finally show dialog
1.2196 + if (dia.exec() == QDialog::Accepted)
1.2197 + {
1.2198 + mapCenter->setAuthor (dia.getAuthor() );
1.2199 + mapCenter->setComment (dia.getComment() );
1.2200 + setChanged();
1.2201 + }
1.2202 +}
1.2203 +
1.2204 +void MapEditor::updateActions()
1.2205 +{
1.2206 + if (getLinkColorHint()==HeadingColor)
1.2207 + actionFormatLinkColorHint->setOn(true);
1.2208 + else
1.2209 + actionFormatLinkColorHint->setOn(false);
1.2210 +
1.2211 + switch (linkstyle)
1.2212 + {
1.2213 + case StyleLine:
1.2214 + actionFormatLinkStyleLine->setOn(true);
1.2215 + break;
1.2216 + case StyleParabel:
1.2217 + actionFormatLinkStyleParabel->setOn(true);
1.2218 + break;
1.2219 + case StylePolyLine:
1.2220 + actionFormatLinkStylePolyLine->setOn(true);
1.2221 + break;
1.2222 + case StylePolyParabel:
1.2223 + actionFormatLinkStylePolyParabel->setOn(true);
1.2224 + break;
1.2225 + default:
1.2226 + break;
1.2227 + }
1.2228 +
1.2229 + QPixmap pix( 16, 16 );
1.2230 + pix.fill( mapCanvas->backgroundColor() );
1.2231 + actionFormatBackColor->setIconSet( pix );
1.2232 + pix.fill( deflinkcolor );
1.2233 + actionFormatLinkColor->setIconSet( pix );
1.2234 +
1.2235 + actionEditUndo->setEnabled( mapChanged );
1.2236 + actionFileSave->setEnabled( mapUnsaved );
1.2237 +
1.2238 + if (selection)
1.2239 + {
1.2240 + if ( (typeid(*selection) == typeid(BranchObj)) ||
1.2241 + (typeid(*selection) == typeid(MapCenterObj)) )
1.2242 + {
1.2243 + standardFlagsDefault->setEnabled (true);
1.2244 +
1.2245 + if ( ((BranchObj*)(selection))->getURL().isEmpty() )
1.2246 + actionEditOpenURL->setEnabled (false);
1.2247 + else
1.2248 + actionEditOpenURL->setEnabled (true);
1.2249 + actionEditURL->setEnabled (true);
1.2250 + actionEditHeading2URL->setEnabled (true);
1.2251 + actionEditBugzilla2URL->setEnabled (true);
1.2252 +
1.2253 + if ( ((BranchObj*)(selection))->getVymLink().isEmpty() )
1.2254 + {
1.2255 + actionEditOpenVymLink->setEnabled (false);
1.2256 + actionEditDeleteVymLink->setEnabled (false);
1.2257 + } else
1.2258 + {
1.2259 + actionEditOpenVymLink->setEnabled (true);
1.2260 + actionEditDeleteVymLink->setEnabled (true);
1.2261 + }
1.2262 + actionEditVymLink->setEnabled (true);
1.2263 +
1.2264 + actionEditCopy->setEnabled (true);
1.2265 + actionEditCut->setEnabled (true);
1.2266 + actionEditPaste->setEnabled (true);
1.2267 + actionEditMoveUp->setEnabled (true);
1.2268 + actionEditMoveDown->setEnabled (true);
1.2269 + actionEditToggleScroll->setEnabled (true);
1.2270 + actionEditHeading->setEnabled (true);
1.2271 + actionEditDelete->setEnabled (true);
1.2272 + actionEditAddBranch->setEnabled (true);
1.2273 + actionEditAddBranchAbove->setEnabled (true);
1.2274 + actionEditAddBranchBelow->setEnabled (true);
1.2275 + actionEditImportAdd->setEnabled (true);
1.2276 + actionEditImportReplace->setEnabled (true);
1.2277 + actionEditSaveBranch->setEnabled (true);
1.2278 + actionEditSelectFirst->setEnabled (true);
1.2279 + actionEditSelectLast->setEnabled (true);
1.2280 + actionEditToggleFloatExport->setEnabled (false);
1.2281 + actionFormatPickColor->setEnabled (true);
1.2282 + actionFormatColorBranch->setEnabled (true);
1.2283 + actionFormatColorSubtree->setEnabled (true);
1.2284 + switch (selection->getFrameType())
1.2285 + {
1.2286 + case NoFrame:
1.2287 + actionFormatFrameNone->setOn(true);
1.2288 + break;
1.2289 + case Rectangle:
1.2290 + actionFormatFrameRectangle->setOn(true);
1.2291 + break;
1.2292 + default:
1.2293 + break;
1.2294 + }
1.2295 + }
1.2296 + if ( (typeid(*selection) == typeid(FloatImageObj)) )
1.2297 + {
1.2298 + standardFlagsDefault->setEnabled (false);
1.2299 +
1.2300 + actionEditOpenURL->setEnabled (false);
1.2301 + actionEditURL->setEnabled (false);
1.2302 + actionEditHeading2URL->setEnabled (false);
1.2303 + actionEditBugzilla2URL->setEnabled (false);
1.2304 + actionEditOpenVymLink->setEnabled (false);
1.2305 + actionEditVymLink->setEnabled (false);
1.2306 + actionEditDeleteVymLink->setEnabled (false);
1.2307 +
1.2308 + actionEditCopy->setEnabled (true);
1.2309 + actionEditCut->setEnabled (true);
1.2310 + actionEditPaste->setEnabled (false); //FIXME
1.2311 + actionEditMoveUp->setEnabled (false);
1.2312 + actionEditMoveDown->setEnabled (false);
1.2313 + actionEditToggleScroll->setEnabled (false);
1.2314 + actionEditHeading->setEnabled (false);
1.2315 + actionEditDelete->setEnabled (true);
1.2316 + actionEditAddBranch->setEnabled (false);
1.2317 + actionEditAddBranchAbove->setEnabled (false);
1.2318 + actionEditAddBranchBelow->setEnabled (false);
1.2319 + actionEditImportAdd->setEnabled (false);
1.2320 + actionEditSaveBranch->setEnabled (false);
1.2321 + actionEditImportReplace->setEnabled (false);
1.2322 + actionEditSelectFirst->setEnabled (false);
1.2323 + actionEditSelectLast->setEnabled (false);
1.2324 + actionEditToggleFloatExport->setOn
1.2325 + ( ((FloatImageObj*)(selection))->getFloatExport() );
1.2326 + actionFormatPickColor->setEnabled (false);
1.2327 + actionFormatColorBranch->setEnabled (false);
1.2328 + actionFormatColorSubtree->setEnabled (false);
1.2329 + }
1.2330 +
1.2331 + } else
1.2332 + {
1.2333 + standardFlagsDefault->setEnabled (false);
1.2334 +
1.2335 + actionEditCopy->setEnabled (false);
1.2336 + actionEditCut->setEnabled (false);
1.2337 + actionEditPaste->setEnabled (false);
1.2338 + actionEditMoveUp->setEnabled (false);
1.2339 + actionEditMoveDown->setEnabled (false);
1.2340 + actionEditToggleScroll->setEnabled (false);
1.2341 + actionEditOpenURL->setEnabled (false);
1.2342 + actionEditURL->setEnabled (false);
1.2343 + actionEditOpenVymLink->setEnabled (false);
1.2344 + actionEditVymLink->setEnabled (false);
1.2345 + actionEditDeleteVymLink->setEnabled (false);
1.2346 + actionEditHeading2URL->setEnabled (false);
1.2347 + actionEditBugzilla2URL->setEnabled (false);
1.2348 + actionEditHeading->setEnabled (false);
1.2349 + actionEditDelete->setEnabled (false);
1.2350 + actionEditAddBranch->setEnabled (false);
1.2351 + actionEditAddBranchAbove->setEnabled (false);
1.2352 + actionEditAddBranchBelow->setEnabled (false);
1.2353 + actionEditSaveBranch->setEnabled (false);
1.2354 + actionEditImportReplace->setEnabled (false);
1.2355 + actionEditSelectFirst->setEnabled (false);
1.2356 + actionEditSelectLast->setEnabled (false);
1.2357 + actionEditToggleFloatExport->setEnabled (false);
1.2358 + actionFormatPickColor->setEnabled (false);
1.2359 + actionFormatColorBranch->setEnabled (false);
1.2360 + actionFormatColorSubtree->setEnabled (false);
1.2361 + }
1.2362 +}
1.2363 +
1.2364 +void MapEditor::setLinkStyle (LinkStyle ls)
1.2365 +{
1.2366 + linkstyle=ls;
1.2367 +
1.2368 + BranchObj *bo;
1.2369 + bo=mapCenter->first();
1.2370 + bo=bo->next();
1.2371 + while (bo)
1.2372 + {
1.2373 + bo->setLinkStyle(bo->getDefLinkStyle());
1.2374 + bo=bo->next();
1.2375 + }
1.2376 + //setChanged();
1.2377 + //saveState();
1.2378 +}
1.2379 +
1.2380 +LinkStyle MapEditor::getLinkStyle ()
1.2381 +{
1.2382 + return linkstyle;
1.2383 +}
1.2384 +
1.2385 +void MapEditor::setLinkColor(QColor c)
1.2386 +{
1.2387 + deflinkcolor=c;
1.2388 + updateActions();
1.2389 +}
1.2390 +
1.2391 +void MapEditor::setLinkColorHint()
1.2392 +{
1.2393 + // called from setLinkColorHint(lch) or at end of parse
1.2394 + BranchObj *bo;
1.2395 + bo=mapCenter->first();
1.2396 + while (bo)
1.2397 + {
1.2398 + bo->setLinkColor();
1.2399 + bo=bo->next();
1.2400 + }
1.2401 +}
1.2402 +
1.2403 +void MapEditor::setLinkColorHint(LinkColorHint lch)
1.2404 +{
1.2405 + linkcolorhint=lch;
1.2406 + setLinkColorHint();
1.2407 +}
1.2408 +
1.2409 +void MapEditor::toggleLinkColorHint()
1.2410 +{
1.2411 + if (linkcolorhint==HeadingColor)
1.2412 + linkcolorhint=DefaultColor;
1.2413 + else
1.2414 + linkcolorhint=HeadingColor;
1.2415 + BranchObj *bo;
1.2416 + bo=mapCenter->first();
1.2417 + while (bo)
1.2418 + {
1.2419 + bo->setLinkColor();
1.2420 + bo=bo->next();
1.2421 + }
1.2422 +}
1.2423 +
1.2424 +LinkColorHint MapEditor::getLinkColorHint()
1.2425 +{
1.2426 + return linkcolorhint;
1.2427 +}
1.2428 +
1.2429 +QColor MapEditor::getDefLinkColor()
1.2430 +{
1.2431 + return deflinkcolor;
1.2432 +}
1.2433 +
1.2434 +void MapEditor::selectLinkColor()
1.2435 +{
1.2436 + // Finish open lineEdits
1.2437 + if (lineedit) finishedLineEditNoSave();
1.2438 +
1.2439 + QColor col = QColorDialog::getColor( deflinkcolor, this );
1.2440 + if ( !col.isValid() ) return;
1.2441 + setLinkColor( col );
1.2442 + setChanged();
1.2443 +}
1.2444 +
1.2445 +void MapEditor::toggleScroll()
1.2446 +{
1.2447 + if (selection && (typeid(*selection) == typeid(BranchObj)) )
1.2448 + {
1.2449 + BranchObj *bo=((BranchObj*)(selection));
1.2450 + if (bo->countBranches()==0) return;
1.2451 + if (bo->getDepth()==0) return;
1.2452 + setChanged();
1.2453 + saveState(PartOfMap,selection);
1.2454 + bo->toggleScroll();
1.2455 + adjustCanvasSize();
1.2456 + canvas()->update();
1.2457 + }
1.2458 +}
1.2459 +
1.2460 +void MapEditor::unScrollAll()
1.2461 +{
1.2462 + BranchObj *bo;
1.2463 + bo=mapCenter->first();
1.2464 + while (bo)
1.2465 + {
1.2466 + if (bo->isScrolled()) bo->toggleScroll();
1.2467 + bo=bo->next();
1.2468 + }
1.2469 +}
1.2470 +
1.2471 +void MapEditor::loadFloatImage ()
1.2472 +{
1.2473 + if (selection &&
1.2474 + (typeid(*selection) == typeid(BranchObj)) ||
1.2475 + (typeid(*selection) == typeid(MapCenterObj)) )
1.2476 + {
1.2477 + BranchObj *bo=((BranchObj*)(selection));
1.2478 +
1.2479 + QFileDialog *fd=new QFileDialog( this,tr("vym - load image"));
1.2480 + fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
1.2481 + ImagePreview *p =new ImagePreview (fd);
1.2482 + fd->setContentsPreviewEnabled( TRUE );
1.2483 + fd->setContentsPreview( p, p );
1.2484 + fd->setPreviewMode( QFileDialog::Contents );
1.2485 + fd->setCaption(tr("vym - Load image"));
1.2486 + fd->setDir (lastImageDir);
1.2487 + fd->show();
1.2488 +
1.2489 + QString fn;
1.2490 + if ( fd->exec() == QDialog::Accepted )
1.2491 + {
1.2492 + setChanged();
1.2493 + saveState(PartOfMap,selection);
1.2494 + QString fn=fd->selectedFile();
1.2495 + lastImageDir=fn.left(fn.findRev ("/"));
1.2496 + bo->addFloatImage();
1.2497 + // FIXME check if load was successful
1.2498 + bo->getLastFloatImage()->load(fn);
1.2499 + bo->getLastFloatImage()->setOriginalFilename(fn);
1.2500 + mapCenter->reposition();
1.2501 + adjustCanvasSize();
1.2502 + canvas()->update();
1.2503 + }
1.2504 + }
1.2505 +}
1.2506 +
1.2507 +void MapEditor::saveFloatImage (int item)
1.2508 +{
1.2509 + if (selection &&
1.2510 + (typeid(*selection) == typeid(FloatImageObj)) )
1.2511 + {
1.2512 + FloatImageObj *fio=((FloatImageObj*)(selection));
1.2513 + const char* fmt = saveImageFormatMenu->text(item);
1.2514 +
1.2515 + QFileDialog *fd=new QFileDialog( this, tr("vym - save image as") + fmt);
1.2516 + fd->addFilter ("PNG (*.png)");
1.2517 + fd->addFilter ("BMP (*.bmp)");
1.2518 + fd->addFilter ("XBM (*.xbm)");
1.2519 + fd->addFilter ("JPG (*.jpg)");
1.2520 + fd->addFilter ("XPM (*.xpm)");
1.2521 + fd->addFilter ("GIF (*.gif)");
1.2522 + fd->addFilter ("PNM (*.pnm)");
1.2523 + fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
1.2524 + fd->setCaption(tr("vym - Save image as ") + fmt);
1.2525 + fd->setMode( QFileDialog::AnyFile );
1.2526 + fd->setSelection (fio->getOriginalFilename());
1.2527 + fd->show();
1.2528 +
1.2529 + QString fn;
1.2530 + if ( fd->exec() == QDialog::Accepted )
1.2531 + {
1.2532 + if (QFile (fd->selectedFile()).exists() )
1.2533 + {
1.2534 + QMessageBox mb( "VYM",
1.2535 + tr("The file ") + fd->selectedFile() +
1.2536 + tr(" exists already. "
1.2537 + "Do you want to overwrite it?"),
1.2538 + QMessageBox::Warning,
1.2539 + QMessageBox::Yes | QMessageBox::Default,
1.2540 + QMessageBox::Cancel | QMessageBox::Escape,
1.2541 + QMessageBox::QMessageBox::NoButton );
1.2542 +
1.2543 + mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
1.2544 + mb.setButtonText( QMessageBox::No, tr("Cancel"));
1.2545 + switch( mb.exec() )
1.2546 + {
1.2547 + case QMessageBox::Yes:
1.2548 + // save
1.2549 + break;;
1.2550 + case QMessageBox::Cancel:
1.2551 + // do nothing
1.2552 + return;
1.2553 + break;
1.2554 + }
1.2555 + }
1.2556 + fio->save (fd->selectedFile(),fmt);
1.2557 + }
1.2558 + }
1.2559 +}
1.2560 +
1.2561 +void MapEditor::toggleFloatExport()
1.2562 +{
1.2563 + if (selection &&
1.2564 + (typeid(*selection) == typeid(FloatImageObj))||
1.2565 + (typeid(*selection) == typeid(FloatObj)) )
1.2566 + {
1.2567 + FloatImageObj *fio=((FloatImageObj*)(selection));
1.2568 + fio->setFloatExport (actionEditToggleFloatExport->isOn() );
1.2569 + }
1.2570 +}
1.2571 +
1.2572 +void MapEditor::setFrame(const FrameType &t)
1.2573 +{
1.2574 + if (selection &&
1.2575 + (typeid(*selection) == typeid(BranchObj)) ||
1.2576 + (typeid(*selection) == typeid(MapCenterObj)) )
1.2577 + {
1.2578 + selection->setFrameType (t);
1.2579 + mapCenter->reposition();
1.2580 + selection->updateLink();
1.2581 + }
1.2582 +}
1.2583 +
1.2584 +void MapEditor::importDir(BranchObj *dst, QDir d)
1.2585 +{
1.2586 + if (selection &&
1.2587 + (typeid(*selection) == typeid(BranchObj)) ||
1.2588 + (typeid(*selection) == typeid(MapCenterObj)) )
1.2589 + {
1.2590 + BranchObj *bo;
1.2591 +
1.2592 + // Traverse directories
1.2593 + d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
1.2594 + const QFileInfoList *dirlist = d.entryInfoList();
1.2595 + QFileInfoListIterator itdir( *dirlist );
1.2596 + QFileInfo *fi;
1.2597 +
1.2598 + while ( (fi = itdir.current()) != 0 )
1.2599 + {
1.2600 + if (fi->fileName() != "." && fi->fileName() != ".." )
1.2601 + {
1.2602 + dst->addBranch();
1.2603 + bo=dst->getLastBranch();
1.2604 + bo->setHeading (fi->fileName() );
1.2605 + bo->setColor (QColor("blue"),false);
1.2606 + bo->toggleScroll();
1.2607 + if ( !d.cd(fi->fileName()) )
1.2608 + QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory"));
1.2609 + else
1.2610 + {
1.2611 + importDir (bo,d);
1.2612 + d.cdUp();
1.2613 + }
1.2614 + }
1.2615 + ++itdir;
1.2616 + }
1.2617 + // Traverse files
1.2618 + d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
1.2619 + const QFileInfoList *filelist = d.entryInfoList();
1.2620 + QFileInfoListIterator itfile( *filelist );
1.2621 +
1.2622 + while ( (fi = itfile.current()) != 0 )
1.2623 + {
1.2624 + dst->addBranch();
1.2625 + bo=dst->getLastBranch();
1.2626 + bo->setHeading (fi->fileName() );
1.2627 + bo->setColor (QColor("black"),false);
1.2628 + ++itfile;
1.2629 + }
1.2630 + }
1.2631 +}
1.2632 +
1.2633 +void MapEditor::importDir()
1.2634 +{
1.2635 + if (selection &&
1.2636 + (typeid(*selection) == typeid(BranchObj)) ||
1.2637 + (typeid(*selection) == typeid(MapCenterObj)) )
1.2638 + {
1.2639 + QFileDialog *fd=new QFileDialog( this,tr("VYM - Choose directory structur to import"));
1.2640 + fd->setMode (QFileDialog::DirectoryOnly);
1.2641 + fd->addFilter (QString (tr("vym map") + " (*.vym)"));
1.2642 + fd->setCaption(tr("VYM - Choose directory structur to import"));
1.2643 + fd->show();
1.2644 +
1.2645 + QString fn;
1.2646 + if ( fd->exec() == QDialog::Accepted )
1.2647 + {
1.2648 + BranchObj *bo=((BranchObj*)(selection));
1.2649 + importDir (bo,QDir(fd->selectedFile()) );
1.2650 + mapCenter->reposition();
1.2651 + adjustCanvasSize();
1.2652 + canvas()->update();
1.2653 + }
1.2654 + }
1.2655 +}
1.2656 +
1.2657 +void MapEditor::testFunction()
1.2658 +{
1.2659 + cout << "MapEditor::testFunction() called\n";
1.2660 +}
1.2661 +
1.2662 +void MapEditor::ensureSelectionVisible()
1.2663 +{
1.2664 + LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
1.2665 + QPoint p;
1.2666 + if (selection->getOrientation() == OrientLeftOfCenter)
1.2667 + p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
1.2668 + else
1.2669 + p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
1.2670 + ensureVisible (p.x(), p.y() );
1.2671 +
1.2672 +}
1.2673 +
1.2674 +void MapEditor::updateViewCenter()
1.2675 +{
1.2676 + // Update movingCenter, so that we can zoom comfortably later
1.2677 + QRect rc = QRect( contentsX(), contentsY(),
1.2678 + visibleWidth(), visibleHeight() );
1.2679 + QRect canvasRect = inverseWorldMatrix().mapRect(rc);
1.2680 + movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
1.2681 + movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
1.2682 +}
1.2683 +
1.2684 +void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e )
1.2685 +{
1.2686 + // Lineedits are already closed by preceding
1.2687 + // mouseEvent, we don't need to close here.
1.2688 +
1.2689 + QPoint p = inverseWorldMatrix().map(e->pos());
1.2690 + LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
1.2691 +
1.2692 + if (lmo)
1.2693 + { // MapObj was found
1.2694 + if (selection != lmo)
1.2695 + {
1.2696 + // select the MapObj
1.2697 + if (selection) selection->unselect();
1.2698 + selection=lmo;
1.2699 + selection->select();
1.2700 + adjustCanvasSize();
1.2701 + }
1.2702 + // Context Menu
1.2703 + if (selection)
1.2704 + {
1.2705 + if (typeid(*selection)==typeid(BranchObj) ||
1.2706 + typeid(*selection)==typeid(MapCenterObj) )
1.2707 + {
1.2708 + // Context Menu on branch or mapcenter
1.2709 + updateActions();
1.2710 + branchContextMenu->popup(e->globalPos() );
1.2711 + }
1.2712 + if (typeid(*selection)==typeid(FloatImageObj))
1.2713 + {
1.2714 + // Context Menu on floatimage
1.2715 + updateActions();
1.2716 + floatimageContextMenu->popup(e->globalPos() );
1.2717 + }
1.2718 + }
1.2719 + } else
1.2720 + { // No MapObj found, we are on the Canvas itself
1.2721 + // Context Menu on Canvas
1.2722 + updateActions();
1.2723 + canvasContextMenu->popup(e->globalPos() );
1.2724 + }
1.2725 +}
1.2726 +
1.2727 +void MapEditor::contentsMousePressEvent(QMouseEvent* e)
1.2728 +{
1.2729 + // Finish open lineEdits
1.2730 + if (lineedit) finishedLineEditNoSave();
1.2731 +
1.2732 + QPoint p = inverseWorldMatrix().map(e->pos());
1.2733 + LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
1.2734 +
1.2735 + // Special case: CTRL is pressed, don't select anything
1.2736 + if (e->state() & QMouseEvent::ControlButton)
1.2737 + {
1.2738 + pickingColor=true;
1.2739 + setCursor (pickColorCursor);
1.2740 + return;
1.2741 + }
1.2742 +
1.2743 + if (lmo)
1.2744 + { // MapObj was found
1.2745 + if (selection != lmo)
1.2746 + {
1.2747 + // select the MapObj
1.2748 + if (selection) selection->unselect();
1.2749 + selection=lmo;
1.2750 + selection->select();
1.2751 +
1.2752 + adjustCanvasSize();
1.2753 + }
1.2754 +
1.2755 + // Check, if systemFlag clicked
1.2756 + if (typeid(*selection)==typeid(BranchObj) ||
1.2757 + typeid(*selection)==typeid(MapCenterObj) )
1.2758 + {
1.2759 + QString foname=((BranchObj*)(selection))->getSystemFlagName(p);
1.2760 + if (!foname.isEmpty())
1.2761 + {
1.2762 + // Do not move, if systemFlag clicked
1.2763 + if (foname=="url")
1.2764 + openURL();
1.2765 + else
1.2766 + if (foname=="vymLink")
1.2767 + {
1.2768 + mainWindow->editOpenVymLink();
1.2769 + // tabWidget may change, better return now
1.2770 + // before segfaulting...
1.2771 + return;
1.2772 + } else
1.2773 + if (foname=="note")
1.2774 + mainWindow->windowToggleNoteEditor();
1.2775 + }
1.2776 + }
1.2777 +
1.2778 + // Left Button Move Branches
1.2779 + if (e->button() == QMouseEvent::LeftButton )
1.2780 + {
1.2781 + movingObj=selection;
1.2782 + movingObj_start.setX( p.x() - selection->x() );
1.2783 + movingObj_start.setY( p.y() - selection->y() );
1.2784 + } else
1.2785 + // Middle Button Toggle Scroll
1.2786 + // (On Mac OS X this won't work, but we still have
1.2787 + // a button in the toolbar)
1.2788 + if (e->button() == QMouseEvent::MidButton )
1.2789 + {
1.2790 + toggleScroll();
1.2791 + }
1.2792 + updateActions();
1.2793 + } else
1.2794 + { // No MapObj found, we are on the Canvas itself
1.2795 + // Left Button move Pos of CanvasView
1.2796 + if (e->button() == QMouseEvent::LeftButton )
1.2797 + {
1.2798 + movingObj=NULL; // move Content not Obj
1.2799 + movingObj_start=e->globalPos();
1.2800 + movingCont_start=QPoint (contentsX(), contentsY() );
1.2801 + movingVec=QPoint(0,0);
1.2802 + setCursor(handOpenCursor);
1.2803 + }
1.2804 + }
1.2805 +}
1.2806 +
1.2807 +void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
1.2808 +{
1.2809 + // Move the selected MapObj
1.2810 + if ( selection && movingObj)
1.2811 + {
1.2812 + QPoint p = inverseWorldMatrix().map(e->pos());
1.2813 +
1.2814 + // Now move the selection, but add relative position (movingObj_start)
1.2815 + // where selection
1.2816 + // was chosen with mousepointer. (This avoids flickering resp. jumping
1.2817 + // of selection back to absPos)
1.2818 +
1.2819 + LinkableMapObj *lmosel;
1.2820 + lmosel = dynamic_cast <LinkableMapObj*> (selection);
1.2821 +
1.2822 + // Check if we could link
1.2823 + LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
1.2824 +
1.2825 +
1.2826 + if (typeid(*selection) == typeid(FloatImageObj))
1.2827 + {
1.2828 + setChanged();
1.2829 + saveState();
1.2830 + FloatObj *fo=(FloatObj*)(selection);
1.2831 + if (fo->getLinkStyle()==StyleUndef)
1.2832 + {
1.2833 + fo->setLinkStyle(fo->getDefLinkStyle());
1.2834 + fo->setLinkColor(fo->getParObj()->getLinkColor());
1.2835 + }
1.2836 + fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
1.2837 + fo->setRelPos();
1.2838 + fo->reposition();
1.2839 +
1.2840 + // Relink float to new mapcenter or branch, if shift is pressed
1.2841 + // Only relink, if selection really has a new parent
1.2842 + if ( (e->state() & QMouseEvent::ShiftButton) && lmo &&
1.2843 + ( (typeid(*lmo)==typeid(BranchObj)) ||
1.2844 + (typeid(*lmo)==typeid(MapCenterObj)) ) &&
1.2845 + ( lmo != fo->getParObj())
1.2846 + )
1.2847 + {
1.2848 + if (typeid(*fo) == typeid(FloatImageObj))
1.2849 + {
1.2850 + FloatImageObj *fio=(FloatImageObj*)(fo);
1.2851 + ((BranchObj*)(lmo))->addFloatImage (fio);
1.2852 + fio->unselect();
1.2853 + ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
1.2854 + fio=((BranchObj*)(lmo))->getLastFloatImage();
1.2855 + fio->setRelPos();
1.2856 + fio->reposition();
1.2857 + selection=(LinkableMapObj*)(fio);
1.2858 + selection->select();
1.2859 + movingObj=(MapObj*)(fio);
1.2860 + // setLinkStyle calls updateLink, only set it once
1.2861 + if (fio->getLinkStyle()!=fio->getDefLinkStyle() )
1.2862 + fio->setLinkStyle (fio->getDefLinkStyle());
1.2863 +
1.2864 + }
1.2865 + // TODO if (typeid(*selection) == typeid(FloatTextObj))
1.2866 + }
1.2867 + } else // selection != a FloatObj
1.2868 + {
1.2869 + if (lmosel->getDepth()==0)
1.2870 + {
1.2871 + if (e->state() == (LeftButton | !ShiftButton))
1.2872 + // If mapCenter is moved, move all the rest by default, too.
1.2873 + mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
1.2874 + else
1.2875 + mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
1.2876 + } else
1.2877 + {
1.2878 + if (lmosel->getDepth()==1)
1.2879 + {
1.2880 + // depth==1, mainbranch
1.2881 + setChanged();
1.2882 + saveState(PartOfMap,lmosel);
1.2883 + lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
1.2884 + } else
1.2885 + {
1.2886 + // depth>1
1.2887 + if (lmosel->getOrientation() == OrientLeftOfCenter)
1.2888 + // Add width of bbox here, otherwise alignRelTo will cause jumping around
1.2889 + lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
1.2890 + p.y()-movingObj_start.y() );
1.2891 + else
1.2892 + lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
1.2893 + }
1.2894 + // reposition subbranch
1.2895 + lmosel->reposition();
1.2896 + ensureSelectionVisible();
1.2897 +
1.2898 + if (lmo && (lmo!=selection) &&
1.2899 + (typeid(*lmo) == typeid(BranchObj) ||
1.2900 + (typeid(*lmo) == typeid(MapCenterObj) )
1.2901 + ) )
1.2902 + {
1.2903 + if (e->state() & QMouseEvent::ControlButton)
1.2904 + {
1.2905 + // Special case: CTRL to link below lmo
1.2906 + lmosel->setParObjTmp (lmo,p,+1);
1.2907 + }
1.2908 + else if (e->state() & QMouseEvent::ShiftButton)
1.2909 + lmosel->setParObjTmp (lmo,p,-1);
1.2910 + else
1.2911 + lmosel->setParObjTmp (lmo,p,0);
1.2912 + } else
1.2913 + {
1.2914 + if (lmo &&(lmo==selection))
1.2915 + // Could link to myself (happens sometimes...)
1.2916 + lmosel->unsetParObjTmp();
1.2917 + if (!lmo)
1.2918 + // no Obj under selection, go back to original Parent
1.2919 + lmosel->unsetParObjTmp();
1.2920 + }
1.2921 + } // depth>0
1.2922 +
1.2923 + } // no FloatImageObj
1.2924 +
1.2925 + canvas()->update();
1.2926 + return;
1.2927 + } // selection && moving_obj
1.2928 +
1.2929 + // Move CanvasView
1.2930 + if (!movingObj && !pickingColor)
1.2931 + {
1.2932 + QPoint p=e->globalPos();
1.2933 + movingVec.setX(-p.x() + movingObj_start.x() );
1.2934 + movingVec.setY(-p.y() + movingObj_start.y() );
1.2935 + setContentsPos( movingCont_start.x() + movingVec.x(),
1.2936 + movingCont_start.y() + movingVec.y());
1.2937 +
1.2938 + updateViewCenter();
1.2939 + }
1.2940 +}
1.2941 +
1.2942 +
1.2943 +void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e)
1.2944 +{
1.2945 + LinkableMapObj *dst;
1.2946 + // Have we been picking color?
1.2947 + if (pickingColor)
1.2948 + {
1.2949 + pickingColor=false;
1.2950 + setCursor (ArrowCursor);
1.2951 + // Check if we are over another branch
1.2952 + dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
1.2953 + if (dst && selection)
1.2954 + {
1.2955 + if (e->state() & QMouseEvent::ShiftButton)
1.2956 + {
1.2957 + ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),false);
1.2958 + ((BranchObj*)(selection))->setLinkColor ();
1.2959 + }
1.2960 + else
1.2961 + {
1.2962 + ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),true);
1.2963 + ((BranchObj*)(selection))->setLinkColor ();
1.2964 + }
1.2965 + }
1.2966 + return;
1.2967 + }
1.2968 + // Have we been moving something?
1.2969 + if ( selection && movingObj )
1.2970 + {
1.2971 + // Check if we are over another branch, but ignore
1.2972 + // any found LMOs, which are FloatObjs
1.2973 + dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ),
1.2974 + ((LinkableMapObj*)(selection)) );
1.2975 +
1.2976 + if (dst &&
1.2977 + (typeid(*dst)!=typeid(BranchObj)&&typeid(*dst)!=typeid(MapCenterObj)))
1.2978 + {
1.2979 + dst=NULL;
1.2980 + }
1.2981 +
1.2982 + // Now check, if we have been moving a branch
1.2983 + if (typeid(*selection) == typeid(BranchObj) )
1.2984 + {
1.2985 + // save the position in case we link to mapcenter
1.2986 + QPoint savePos=QPoint (selection->x(),selection->y() );
1.2987 +
1.2988 + // Reset the temporary drawn link to the original one
1.2989 + ((LinkableMapObj*)(selection))->unsetParObjTmp();
1.2990 +
1.2991 + if (dst )
1.2992 + {
1.2993 + setChanged();
1.2994 + saveState();
1.2995 + // TODO we also could check, if dest and src are on same branch,
1.2996 + // then it would be sufficient to saveState of this branch
1.2997 +
1.2998 + // FIXME better introduce BO::move to speed up and keep IDs
1.2999 + copy(); // copy selection to clipboard
1.3000 + cutNoSave(); // remove selection here
1.3001 +
1.3002 + selection->unselect();
1.3003 + selection=dst;
1.3004 + // Modifiers allow to insert above/below dst
1.3005 + if (e->state() & QMouseEvent::ShiftButton)
1.3006 + {
1.3007 + selection=pasteAtNoSave (((BranchObj*)(dst))->getNum());
1.3008 + if (selection) selection->select();
1.3009 + }
1.3010 + else if (e->state() & QMouseEvent::ControlButton)
1.3011 + {
1.3012 + selection=pasteAtNoSave (((BranchObj*)(dst))->getNum()+1);
1.3013 + if (selection) selection->select();
1.3014 + }
1.3015 + else
1.3016 + {
1.3017 + selection=pasteNoSave();
1.3018 + selection->select();
1.3019 + if (dst->getDepth()==0)
1.3020 + ((BranchObj*)(selection))->move (savePos);
1.3021 + }
1.3022 + }
1.3023 + // Draw the original link, before selection was moved around
1.3024 + mapCenter->reposition();
1.3025 + }
1.3026 + // Finally resize canvas, if needed
1.3027 + adjustCanvasSize();
1.3028 + canvas()->update();
1.3029 + movingObj=NULL;
1.3030 + } else
1.3031 + { // maybe we moved View: set old cursor
1.3032 + setCursor (ArrowCursor);
1.3033 + }
1.3034 +}
1.3035 +
1.3036 +void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
1.3037 +{
1.3038 + // Finish open lineEdits
1.3039 + if (lineedit) finishedLineEditNoSave();
1.3040 +
1.3041 + if (e->button() == QMouseEvent::LeftButton )
1.3042 + {
1.3043 + QPoint p = inverseWorldMatrix().map(e->pos());
1.3044 + LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
1.3045 + if (lmo) { // MapObj was found
1.3046 + // First select the MapObj than edit heading
1.3047 + if (selection) selection->unselect();
1.3048 + selection=lmo;
1.3049 + selection->select();
1.3050 + setChanged();
1.3051 + saveState(PartOfMap,selection);
1.3052 + editHeading();
1.3053 + }
1.3054 + }
1.3055 +}
1.3056 +
1.3057 +void MapEditor::resizeEvent (QResizeEvent* e)
1.3058 +{
1.3059 + QCanvasView::resizeEvent( e );
1.3060 +
1.3061 + QString s="";
1.3062 + if (!fileName.isEmpty()) s=fileName;
1.3063 + adjustCanvasSize();
1.3064 +}
1.3065 +