1 /*
2 Copyright 2010-2012 Sergey Levin
3
4
5 This file is part of crosti.
6
7 Crosti is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Crosti is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with crosti. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21
22 #include "mainwindow.h"
23 #include "imagefilter.h"
24 #include "progressdialog.h"
25 #include "schemedata.h"
26 #include "toolbar.h"
27 #include "info.h"
28 #include "history.h"
29 #include "cminimap.h"
30 #include "cimageviewer.h"
31 #include "cschemeviewer.h"
32 #include "cviewportwatcher.h"
33 #include "sprite.h"
34
35 #include <QTranslator>
36 #include <QDesktopWidget>
37 #include <QColor>
38 #include <QStatusBar>
39 #include <QMenuBar>
40 #include <QColorDialog>
41 #include <QFontDialog>
42 #include <QFileDialog>
43 #include <QStyleFactory>
44 #include <QStandardItemModel>
45 #include <QImageReader>
46 #include <QImageWriter>
47 #include <QTime>
48 #include <QMessageBox>
49 #include <QtCore/qmath.h>
50
51 #if QT_VERSION >= 0x050000
52 #include <QtPrintSupport/QPrintPreviewDialog>
53 #else
54 #include <QPrintPreviewDialog>
55 #endif
56
57
58
59 int dL=2;//Превышение ширины толстой линии по сравнению с тонкой
60 int linePix=3;//Ширина тонкой линии
61 int lineBoldPix=linePix+dL;//Ширина толстой линии
62 int dl=6;//Превышение ширины ребра клетки над шириной пиктограммы
63
64 int square=0;//Квадрат загруженной (или созданной) схемы
65
66 const QString NO_STYLE = "none";
67
68
69
installTranslator(const QString & language)70 void installTranslator(const QString &language)
71 {
72 static QTranslator *translator_qt = 0;
73 static QTranslator *translator_app = 0;
74
75 if (translator_qt) {
76 QApplication::removeTranslator(translator_qt);
77 delete translator_qt;
78 }
79
80 if (translator_app) {
81 QApplication::removeTranslator(translator_app);
82 delete translator_app;
83 }
84
85 if (language != "en") {
86 //---Загрузка переводчика для внутренних классов qt
87 translator_qt = new QTranslator(qApp);
88 if (translator_qt->load("qt_" + language,
89 Info::dataPath() + "/system/translations"))
90 QApplication::installTranslator(translator_qt);
91
92 //---Загрузка переводчика программы
93 translator_app = new QTranslator(qApp);
94 if (translator_app->load("crosti_" + language,
95 Info::dataPath() + "/system/translations"))
96 QApplication::installTranslator(translator_app);
97 }
98 }
99
100
101
scaleToDesktop(const QSize & sz)102 static float scaleToDesktop(const QSize &sz){
103 int w=QApplication::desktop()->availableGeometry().width();
104 int h=QApplication::desktop()->availableGeometry().height();
105 float scaleW=w,scaleH=h;
106 if(sz.width()>w)scaleW/=sz.width();else scaleW=1;
107 if(sz.height()>h)scaleH/=sz.height();else scaleH=1;
108 return (scaleW>scaleH)?scaleH:scaleW;
109 }
110
111
112
analyzeSuffix(QString ext)113 int MainWindow::analyzeSuffix(QString ext){
114 ext = ext.toLower();
115 if (QImageReader::supportedImageFormats().contains(ext.toLatin1()))
116 return 0;
117 if (ext == "cst")
118 return 1;
119 if (ext == "pdf")
120 return 2;
121
122 return -1;
123 }
124
125
126
checkSuffix(QString * fileName,QString nameFilter)127 void MainWindow::checkSuffix(QString *fileName,QString nameFilter)
128 {
129 QFileInfo fi(*fileName);
130 if(fi.suffix()==""){
131 nameFilter.chop(1);
132 QString filter=nameFilter.section('.',1);
133 QStringList extList=filter.split(" *.",QString::SkipEmptyParts,Qt::CaseInsensitive);
134 if(extList.size()!=0)*fileName+="."+extList.at(0);
135 }
136 }
137
138
139
schemeModify(QStandardItem * item)140 void MainWindow::schemeModify(QStandardItem *item)
141 {
142 int row=item->row();
143 QColor cl=QColor();
144 QColor colorNew=QColor();
145
146
147 if(item->column()==0){
148 QRgb clNew(item->data(Qt::UserRole).toUInt());
149 QRgb clOld=colorTable.at(row);
150
151 cl.setRgba(clOld);
152 colorNew.setRgba(clNew);
153
154 colorTable.replace(row,clNew);
155
156 try{
157 ColorItem* ci=view->colorItem(row,clOld);
158 if(ci->size()!=0){
159 connect(ci,SIGNAL(changed(int,QColor)),SLOT(colorUpdate(int,QColor)));
160 view->history.append(ci);
161 }
162 }catch(const std::bad_alloc&){
163 Info::messageSplash(Info::msgOutOfMemory);
164 }
165
166 view->colorUpdate(cl,colorNew);
167 setColor(row);
168 }
169 if(item->column()==1){
170 int num=item->data(Qt::UserRole).toInt();
171
172 id[row]=num;
173
174 QModelIndex index1=paletteModel->index(row,0);
175 cl.setRgba(QRgb(paletteModel->data(index1,Qt::UserRole).toUInt()));
176
177 try{
178 IconItem* ii=view->iconItem(row,cl);
179 if(ii->size()!=0){
180 connect(ii,SIGNAL(changed(int,int)),SLOT(iconUpdate(int,int)));
181 view->history.append(ii);
182 }
183 }catch(const std::bad_alloc&){
184 Info::messageSplash(Info::msgOutOfMemory);
185 }
186
187 view->iconUpdate(cl,num);
188 view->setIconSelected(num);
189 view->update();
190 }
191
192
193 _isColorTableUpdated=true;
194 if(ui.tabWidget->currentIndex()==2)colorTableCreate(true);
195 }
196
197
setColor(int row)198 void MainWindow::setColor(int row){
199 QModelIndex index1=paletteModel->index(row,0);
200 QModelIndex index2=paletteModel->index(row,1);
201 ui.tvPalette->selectionModel()->setCurrentIndex(index1,QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows);
202 QColor cl;
203 cl.setRgba(QRgb(paletteModel->data(index1,Qt::UserRole).toUInt()));
204 int id=paletteModel->data(index2,Qt::UserRole).toInt();
205 view->setIconSelected(id);
206 view->setColorSelected(cl);
207 view->update();
208 }
209
210
setColor(const QModelIndex & index)211 void MainWindow::setColor(const QModelIndex &index){
212 setColor(index.row());
213 }
214
215
setClPicCount()216 void MainWindow::setClPicCount(){
217 QDir clpicDir(Info::dataPath()+"/system/clpics");
218 QStringList filter;
219 filter.append("clpic*.bmp");
220 _clpicCount=clpicDir.entryList(filter,QDir::Files).count();
221 }
222
223
setImageList(int squarePix,int dl)224 void MainWindow::setImageList(int squarePix,int dl){
225 for(int i=0;i<_clpicCount;i++){
226 QImage image(Info::dataPath()+"/system/clpics/clpic"+QString::number(i)+".bmp");
227 image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
228 image=image.scaled(squarePix-2*dl,squarePix-2*dl);
229 image.setAlphaChannel(image.createMaskFromColor(0xFFFFFFFF,Qt::MaskOutColor));
230 imageList.append(image);
231 }
232 }
233
234
MainWindow(QString fileName,QWidget * parent)235 MainWindow::MainWindow(QString fileName,QWidget *parent):QMainWindow(parent),
236 MiniMap(new CMiniMap),
237 MiniMapRectColor(Qt::white)
238 {
239 Info::setParent(this);
240 setDockOptions(QMainWindow::AnimatedDocks);
241
242
243 _isSchemeCreated=false;
244 _schemeName="";
245 _imageName="";
246 _isColorTableUpdated=false;
247 _isSchemeUpdated=false;
248 _isConverted=false;
249
250 imgH=0;
251 imgW=0;
252 _angle=0;
253 colorTable.clear();
254 _bkColor=Qt::white;
255
256 setClPicCount();
257
258 imageList.clear();
259
260
261 view=new View(QSize(0,0));
262
263
264 for(int i=0;i<_clpicCount;i++){
265 QImage image(Info::dataPath()+"/system/clpics/clpic"+QString::number(i)+".bmp");
266 image.setAlphaChannel(image.createMaskFromColor(0xFFFFFFFF,Qt::MaskOutColor));
267 imageList.append(image);
268 }
269
270
271
272
273 QSettings rsettings(QApplication::organizationName(),QApplication::applicationName());
274
275
276 MiniMapRectColor = rsettings.value("miniMapRectColor", QColor(Qt::white)).value<QColor>();
277
278
279 if(!rsettings.contains("wizard"))rsettings.setValue("wizard",true);
280 bool showWizard=rsettings.value("wizard").value<bool>();
281
282 if(!rsettings.contains("invertIcons"))rsettings.setValue("invertIcons",false);
283 if(!rsettings.contains("showGrid"))rsettings.setValue("showGrid",true);
284 if(!rsettings.contains("showIcons"))rsettings.setValue("showIcons",true);
285 if (!rsettings.contains("showColors")) rsettings.setValue("showColors", true);
286
287
288 if(!rsettings.contains("theme"))rsettings.setValue("theme","default");
289
290
291 if (!rsettings.contains("style")) {
292 QStringList styles = QStyleFactory::keys();
293 rsettings.setValue("style", styles.isEmpty() ?
294 NO_STYLE :
295 styles.first());
296 }
297 setStyle(rsettings.value("style").value<QString>());
298
299
300 if(!rsettings.contains("units"))rsettings.setValue("units",0);
301 setUnits(rsettings.value("units").value<int>());
302
303
304 if(!rsettings.contains("picturePath")){
305 //DATA_PATH!="" на Unix системах
306 if(QString(DATA_PATH)=="")rsettings.setValue("picturePath",Info::dataPath()+"/picture");
307 else rsettings.setValue("picturePath",QDir::homePath());
308 }
309 _picturePath=rsettings.value("picturePath").value<QString>();
310
311
312 if(!rsettings.contains("schemePath")){
313 //DATA_PATH!="" на Unix системах
314 if(QString(DATA_PATH)=="")rsettings.setValue("schemePath",Info::dataPath()+"/scheme");
315 else rsettings.setValue("schemePath",QDir::homePath());
316 }
317 _schemePath=rsettings.value("schemePath").value<QString>();
318
319 _mainFont=rsettings.value("font/mainfont").value<QFont>();
320
321
322 _mainFontHalf=_mainFont;
323 if (_mainFont.pointSize() >= 14)
324 _mainFontHalf.setPointSize(int(_mainFontHalf.pointSizeF() / 2));
325 else
326 _mainFontHalf.setPointSize(7);
327
328 _mainFontBold=_mainFont;
329 _mainFontBold.setBold(true);
330
331 _mainFontHalfBold=_mainFont;
332 if (_mainFont.pointSize() >= 14)
333 _mainFontHalfBold.setPointSize(int(_mainFontHalfBold.pointSizeF() / 2));
334 else
335 _mainFontHalfBold.setPointSize(7);
336 _mainFontHalfBold.setBold(true);
337
338
339 _language = Info::language();
340
341
342 programsettingsWindow=NULL;
343
344 ui.setupUi(this);
345
346
347 for(int i=0;i<ui.tabWidget->count();i++)
348 ui.tabWidget->setTabIcon(i,QIcon(Info::dataPath()+"/system/image/"+QString::number(i+1)+".png"));
349
350
351 //ui.imageView->setFocusProxy(ui.scaleSlider);
352
353
354 delegate=new comboBoxDelegate(&palette);
355 paletteModel=new QStandardItemModel(0,2);
356
357 ui.tvPalette->setModel(paletteModel);
358 paletteModel->setHeaderData(0,Qt::Horizontal,trUtf8("Color"),Qt::DisplayRole);
359 paletteModel->setHeaderData(1,Qt::Horizontal,trUtf8("Icon"),Qt::DisplayRole);
360 ui.tvPalette->setSelectionBehavior(QAbstractItemView::SelectRows);
361 ui.tvPalette->setSelectionMode(QAbstractItemView::SingleSelection);
362
363 ui.tvPalette->setItemDelegate(delegate);
364
365 connect(ui.tvPalette,SIGNAL(clicked(const QModelIndex&)),this,SLOT(setColor(const QModelIndex&)));
366
367 if (!rsettings.contains("schemeFilter")) rsettings.setValue("schemeFilter", 0);
368 ui.filterCb->setCurrentIndex(rsettings.value("schemeFilter").value<int>());
369 if(!rsettings.contains("schemeSquare"))rsettings.setValue("schemeSquare",36);
370 ui.squareSB->setValue(rsettings.value("schemeSquare").value<int>());
371 if(!rsettings.contains("toolLine"))rsettings.setValue("toolLine",2);
372 ui.sbLineWidth->setValue(rsettings.value("toolLine").value<int>());
373 if(!rsettings.contains("toolLineMode"))rsettings.setValue("toolLineMode",0);
374 ui.cbLineMode->setCurrentIndex(rsettings.value("toolLineMode").value<int>());
375 if(!rsettings.contains("crostiSquare"))rsettings.setValue("crostiSquare",14);
376 ui.squareSB1->setValue(rsettings.value("crostiSquare").value<int>());
377 if(!rsettings.contains("schemeLine"))rsettings.setValue("schemeLine",2);
378 ui.lineSB->setValue(rsettings.value("schemeLine").value<int>());
379 if(!rsettings.contains("crostiLine"))rsettings.setValue("crostiLine",3);
380 ui.lineSB1->setValue(rsettings.value("crostiLine").value<int>());
381 if(!rsettings.contains("crostiDl"))rsettings.setValue("crostiDl",3);
382 ui.dlSB->setValue(rsettings.value("crostiDl").value<int>());
383 if(!rsettings.contains("crostiColor"))rsettings.setValue("crostiColor", QColor(Qt::white));
384 _bkColor=rsettings.value("crostiColor").value<QColor>();
385 if(_bkColor.isValid())setBackground(_bkColor);
386
387
388 restoreGeometry(rsettings.value("windowGeometry").toByteArray());
389 restoreState(rsettings.value("windowState").toByteArray());
390
391 setFont(_mainFont);
392 setWindowIcon(QIcon(Info::dataPath()+"/system/image/crosti.png"));
393 setWindowTitle(QApplication::applicationName());
394 setStatusBar(new QStatusBar());
395
396
397 QList<QDockWidget*> dockWidget = QList<QDockWidget*>() << ui.dwImage
398 << ui.dwPalette
399 << ui.dwTool
400 << ui.dwCrosti
401 << ui.dwMiniMap;
402 for (int i = 0; i < dockWidget.count(); ++i) {
403 dockWidget[i]->setEnabled(false);
404 dockWidget[i]->setWindowIcon(QIcon(Info::dataPath()+"/system/image/" + QString::number(i+1) + ".png"));
405 }
406
407
408 ui.dwMiniMap->setEnabled(true);
409 ui.dwMiniMap->setWidget(MiniMap);
410
411
412 /*
413 ui.dwImage->setEnabled(false);
414 ui.dwPalette->setEnabled(false);
415 ui.dwTool->setEnabled(false);
416 ui.dwCrosti->setEnabled(false);
417 ui.dwMiniMap->setEnabled(false);
418
419 ui.dwImage->setWindowIcon(QIcon(Info::dataPath()+"/system/image/1.png"));
420 ui.dwPalette->setWindowIcon(QIcon(Info::dataPath()+"/system/image/2.png"));
421 ui.dwTool->setWindowIcon(QIcon(Info::dataPath()+"/system/image/3.png"));
422 ui.dwCrosti->setWindowIcon(QIcon(Info::dataPath()+"/system/image/4.png"));
423 ui.dwMiniMap->setWindowIcon(QIcon(Info::dataPath()+"/system/image/5.png"));
424 */
425 ui.priceBtn->setVisible(false);
426 if(_language=="ru")ui.priceBtn->setVisible(true);
427
428
429
430 imageViewer=new CImageViewer(NULL, MiniMap, this);
431 ui.verticalLayout_3->insertWidget(0,imageViewer);
432
433
434 schemeViewer=new CSchemeViewer(view, MiniMap, this);
435 ui.verticalLayout_7->insertWidget(0,schemeViewer);
436
437
438 crostiViewer=new CImageViewer(NULL, MiniMap, this);
439 ui.verticalLayout_8->insertWidget(0,crostiViewer);
440
441
442 colorViewer=new CImageViewer(NULL, MiniMap, this);
443 ui.verticalLayout_9->insertWidget(0,colorViewer);
444
445
446
447 ui.rbSType1->setIcon(QIcon(Info::dataPath()+"/system/image/stitch.png"));
448 ui.rbSType2->setIcon(QIcon(Info::dataPath()+"/system/image/lstitch.png"));
449 ui.rbSType3->setIcon(QIcon(Info::dataPath()+"/system/image/rstitch.png"));
450 ui.previewBtn->setIcon(QIcon(Info::dataPath()+"/system/image/eye.png"));
451 ui.imageResetBtn->setIcon(QIcon(Info::dataPath()+"/system/image/imagereset.png"));
452 ui.rotLeftBtn->setIcon(QIcon(Info::dataPath()+"/system/image/rotl.png"));
453 ui.rotRightBtn->setIcon(QIcon(Info::dataPath()+"/system/image/rotr.png"));
454 //ui.scaleResetBtn->setIcon(QIcon(Info::dataPath()+"/system/image/zoomreset.png"));
455 //ui.scaleResetBtn1->setIcon(QIcon(Info::dataPath()+"/system/image/zoomreset.png"));
456 //ui.scaleResetBtn2->setIcon(QIcon(Info::dataPath()+"/system/image/zoomreset.png"));
457 //ui.scaleResetBtn3->setIcon(QIcon(Info::dataPath()+"/system/image/zoomreset.png"));
458 ui.addColorBtn->setIcon(QIcon(Info::dataPath()+"/system/image/plus.png"));
459 ui.removeColorBtn->setIcon(QIcon(Info::dataPath()+"/system/image/minus.png"));
460 ui.schemeBtn->setIcon(QIcon(Info::dataPath()+"/system/image/2.png"));
461 ui.crostiBtn->setIcon(QIcon(Info::dataPath()+"/system/image/4.png"));
462 ui.crostiClearBtn->setIcon(QIcon(Info::dataPath()+"/system/image/clear.png"));
463 ui.priceBtn->setIcon(QIcon(Info::dataPath()+"/system/image/money.png"));
464 ui.chbInvert->setIcon(QIcon(Info::dataPath()+"/system/image/invert.png"));
465
466 ui.rbc->setVisible(false);
467
468
469 infoLabel=new QLabel(this);
470 infoLabel->setMinimumWidth(70);
471 infoLabel->setAlignment(Qt::AlignRight);
472 statusBar()->addPermanentWidget(infoLabel);
473 sizeLabel=new QLabel(this);
474 sizeLabel->setMinimumWidth(150);
475 sizeLabel->setAlignment(Qt::AlignRight);
476 statusBar()->addPermanentWidget(sizeLabel);
477
478 wizard=new crostiWizard(&palette, this);
479 connect(wizard,SIGNAL(accepted()),SLOT(wizardAccepted()));
480
481
482 //connect(ui.scaleSB0,SIGNAL(valueChanged(int)),SLOT(setScaleImage(int)));
483 //connect(ui.scaleSB1,SIGNAL(valueChanged(int)),SLOT(setScaleScheme(int)));
484 //connect(ui.scaleSB2,SIGNAL(valueChanged(int)),SLOT(setScaleColorTable(int)));
485 //connect(ui.scaleSB3,SIGNAL(valueChanged(int)),SLOT(setScaleCrosti(int)));
486 connect(ui.squareSB1,SIGNAL(valueChanged(int)),SLOT(crostiSizeShow(int)));
487
488 //connect(ui.scaleResetBtn,SIGNAL(clicked()),SLOT(scaleResetBtnPress()));
489 //connect(ui.scaleResetBtn1,SIGNAL(clicked()),SLOT(scaleResetBtn1Press()));
490 //connect(ui.scaleResetBtn2,SIGNAL(clicked()),SLOT(scaleResetBtn2Press()));
491 //connect(ui.scaleResetBtn3,SIGNAL(clicked()),SLOT(scaleResetBtn3Press()));
492
493 connect(ui.schemeBtn,SIGNAL(clicked()),SLOT(schemeBtnPress()));
494 connect(ui.colorBtn,SIGNAL(clicked()),SLOT(colorBtnPress()));
495 connect(ui.backColorBtn,SIGNAL(clicked()),SLOT(backColorBtnPress()));
496 connect(ui.previewBtn,SIGNAL(clicked()),SLOT(previewBtnPress()));
497 connect(ui.priceBtn,SIGNAL(clicked()),SLOT(priceBtnPress()));
498 connect(ui.crostiBtn,SIGNAL(clicked()),SLOT(crostiBtnPress()));
499 connect(ui.crostiClearBtn,SIGNAL(clicked()),SLOT(crostiClear()));
500 connect(ui.imageResetBtn,SIGNAL(clicked()),SLOT(imageResetBtnPress()));
501 connect(ui.rotLeftBtn,SIGNAL(clicked()),SLOT(imageRotateLeft()));
502 connect(ui.rotRightBtn,SIGNAL(clicked()),SLOT(imageRotateRight()));
503
504 connect(ui.addColorBtn,SIGNAL(clicked()),SLOT(addColorBtnPress()));
505 connect(ui.removeColorBtn,SIGNAL(clicked()),SLOT(removeColorBtnPress()));
506
507 connect(ui.widthSB,SIGNAL(valueChanged(int)),this,SLOT(uncheckRbx()));
508 connect(ui.heightSB,SIGNAL(valueChanged(int)),this,SLOT(uncheckRbx()));
509
510 connect(ui.squareSB,SIGNAL(valueChanged(int)),SLOT(setSquareSBtoolTip()));
511 connect(ui.squareSB,SIGNAL(valueChanged(int)),SLOT(squareChanged(int)));
512 connect(ui.lineSB,SIGNAL(valueChanged(int)),SLOT(setSquareSBtoolTip()));
513 connect(ui.lineSB,SIGNAL(valueChanged(int)),view,SLOT(setLinePix(int)));
514
515 connect(ui.sbLineWidth,SIGNAL(valueChanged(int)),SLOT(setLine(int)));
516 connect(ui.cbLineMode,SIGNAL(activated(int)),SLOT(setLine(int)));
517
518 connect(ui.rbSType1,SIGNAL(clicked()),view,SLOT(setStitchCross()));
519 connect(ui.rbSType2,SIGNAL(clicked()),view,SLOT(setStitchLeft()));
520 connect(ui.rbSType3,SIGNAL(clicked()),view,SLOT(setStitchRight()));
521
522 connect(ui.chbInvert,SIGNAL(toggled(bool)),view,SLOT(setSpriteIconInvert(bool)));
523 connect(ui.chbGridShow,SIGNAL(toggled(bool)),view,SLOT(setGrid(bool)));
524 connect(ui.chbIconShow,SIGNAL(toggled(bool)),view,SLOT(setIcons(bool)));
525 connect(ui.chbColorShow, SIGNAL(toggled(bool)), view, SLOT(setColors(bool)));
526 connect(ui.tabWidget,SIGNAL(currentChanged(int)),SLOT(updateTab(int)));
527 connect(view,SIGNAL(colorSelected(QPixmap)),ui.lbColor,SLOT(setPixmap(QPixmap)));
528 connect(view, SIGNAL(updated()), SLOT(updateTracking()));
529 //connect(view, SIGNAL(updated()), SLOT(updateMiniMap()));
530
531 ui.chbInvert->setChecked(rsettings.value("invertIcons").value<bool>());
532 ui.chbGridShow->setChecked(rsettings.value("showGrid").value<bool>());
533 ui.chbIconShow->setChecked(rsettings.value("showIcons").value<bool>());
534 ui.chbColorShow->setChecked(rsettings.value("showColors").value<bool>());
535 ui.widgetStitch->setVisible(false);
536 ui.widgetGrid->setVisible(false);
537 ui.widgetIcon->setVisible(false);
538 ui.widgetColor->setVisible(false);
539 ui.widgetLine->setVisible(false);
540
541
542 //QPixmap px(20,20);
543 //px.fill(Qt::transparent);
544 //ui.lbColor->setPixmap(px);
545 setLabelColor(ui.lbColor, Qt::transparent);
546
547
548
549 createActions();
550 createMenus();
551
552
553 show();
554
555 QFileInfo fi(fileName);
556 QString suff=fi.suffix().toLower();
557 if(QImageReader::supportedImageFormats().contains(suff.toLatin1()))openImage(fileName);
558 if(suff=="cst")openScheme(fileName);
559
560
561 if((showWizard)&&(fileName==""))wizardDialog();
562
563
564 lbPreview=new previewLabel();
565
566
567 QAbstractButton* btn;
568 QList<QAbstractButton*>btnList=ToolBar::instance()->buttonGroup()->buttons();
569 foreach(btn,btnList){
570 ui.horizontalLayout_6->addWidget(btn);
571 connect(btn,SIGNAL(clicked()),view,SLOT(update()));
572 }
573
574 btn=ToolBar::instance()->buttonGroup()->button(ToolBar::stitchType);
575 connect(btn,SIGNAL(toggled(bool)),ui.widgetStitch,SLOT(setVisible(bool)));
576 btn=ToolBar::instance()->buttonGroup()->button(ToolBar::gridShow);
577 connect(btn,SIGNAL(toggled(bool)),ui.widgetGrid,SLOT(setVisible(bool)));
578 btn=ToolBar::instance()->buttonGroup()->button(ToolBar::iconShow);
579 connect(btn,SIGNAL(toggled(bool)),ui.widgetIcon,SLOT(setVisible(bool)));
580
581 btn=ToolBar::instance()->buttonGroup()->button(ToolBar::colorShow);
582 connect(btn, SIGNAL(toggled(bool)), ui.widgetColor, SLOT(setVisible(bool)));
583
584 btn=ToolBar::instance()->buttonGroup()->button(ToolBar::lineDraw);
585 connect(btn,SIGNAL(toggled(bool)),ui.widgetLine,SLOT(setVisible(bool)));
586 connect(btn,SIGNAL(toggled(bool)),SLOT(setLine(bool)));
587
588 if (palette.color.isEmpty())
589 Info::message(QObject::trUtf8("Color palette not found!"));
590 }
591
592
593
setLanguage(const QString & lang)594 void MainWindow::setLanguage(const QString &lang)
595 {
596 _language = lang;
597 uiprogramsettings.lbStatus->setText(Info::message(Info::msgRestart));
598 }
599
600
setPalette(const QString & name)601 void MainWindow::setPalette(const QString &name)
602 {
603 QSettings rsettings(QApplication::organizationName(), QApplication::applicationName());
604 rsettings.setValue("palette", name);
605 uiprogramsettings.lbStatus->setText(Info::message(Info::msgRestart));
606 }
607
608
setLabelColor(QLabel * label,const QColor & cl)609 void MainWindow::setLabelColor(QLabel *label, const QColor& cl){
610 QPixmap px(20,20);
611 px.fill(cl);
612 label->setPixmap(px);
613 }
614
615
updateTracking()616 void MainWindow::updateTracking()
617 {
618 _isColorTableUpdated=true;
619 _isSchemeUpdated=true;
620 updateTab(ui.tabWidget->currentIndex());
621 }
622
623
updateMiniMap()624 void MainWindow::updateMiniMap()
625 {
626 if (ui.tabWidget->currentIndex() == 1 && ui.dwMiniMap->isVisible())
627 MiniMap->updateImage(schemeViewer->image());
628 }
629
630
setLine(bool b)631 void MainWindow::setLine(bool b){
632 if(b)setLine();
633 else view->setLine(View::LineMode());
634 }
635
636
setLine(int)637 void MainWindow::setLine(int){
638 view->setLine(View::LineMode(ui.sbLineWidth->value(),ui.cbLineMode->currentIndex()));
639 }
640
641
642
rotate(QImage image,int angle) const643 QImage MainWindow::rotate(QImage image,int angle)const{
644 double a = M_PI/180*angle;
645 double sina = qSin(a);
646 double cosa = qCos(a);
647 QMatrix rotationMatrix(cosa, sina, -sina, cosa, 0, 0);
648 return image.transformed(rotationMatrix);
649 }
650
imageRotateLeft()651 void MainWindow::imageRotateLeft(){
652 _angle-=90;
653 imageRotate();
654 }
655
imageRotateRight()656 void MainWindow::imageRotateRight(){
657 _angle+=90;
658 imageRotate();
659 }
660
imageRotate()661 void MainWindow::imageRotate(){
662 if(_angle>180)_angle-=360;
663 if(_angle<-180)_angle+=360;
664 _image=rotate(_imageEtalon,_angle);
665 showImage(_image);
666 }
667
backColorBtnPress()668 void MainWindow::backColorBtnPress(){
669 view->setColorSelected(_bkColor);
670 view->setIconSelected(INT_MAX);//Если присвоить NO_ICON не будет работать история
671 setLabelColor(ui.lbColor, _bkColor);
672 }
673
colorBtnPress()674 void MainWindow::colorBtnPress(){
675 _bkColor=QColorDialog::getColor(Qt::black,this);
676 if(_bkColor.isValid())setBackground(_bkColor);
677 }
678
679
setBackground(const QColor & cl)680 void MainWindow::setBackground(const QColor &cl)
681 {
682 view->setBackground(cl);
683 QPixmap pic(16,16);
684 pic.fill(cl);
685 ui.colorBtn->setIcon(QIcon(pic));
686 ui.backColorBtn->setIcon(QIcon(pic));
687 }
688
689
690
imageResetBtnPress()691 void MainWindow::imageResetBtnPress(){
692 _isConverted=false;
693 _image=_imageEtalon;
694 _angle=0;
695 showImage(_image);
696 }
697
698
699
uncheckRbx()700 void MainWindow::uncheckRbx(){
701 ui.rbc->setChecked(true);
702 }
703
704
crostiClear()705 void MainWindow::crostiClear()
706 {
707 crostiViewer->scene()->clear();
708 _crostiName.clear();
709 }
710
711 /*
712 void MainWindow::resetCrosti(){
713 crostiScene->clear();
714 crostiScene->setSceneRect(ui.crostiView->rect());
715 }
716 */
crostiBtnPress()717 void MainWindow::crostiBtnPress()
718 {
719 _crostiName.clear();
720 //Не переделывать в рисование на crostiScene - конвертация и масштаб работают медленнее
721 //int squarePix=int(254/ui.squareSB1->value());//Ребро клетки
722 int squarePix=20;
723
724 QSize szI(squarePix*view->schemeSize());
725 float scale=_imageFilter::scaleFit(szI,24);
726 if(!isMemoryAvailable(4*qPow(scale,2)*szI.width()*szI.height())){
727 Info::messageSplash(Info::msgOutOfMemory);
728 return;
729 }
730
731
732
733 QPixmap img(scale*szI);
734 img.fill(_bkColor.rgb());
735 //Рисунок может быть isNull из-за нехватки памяти
736 if(img.isNull()){
737 Info::messageSplash(trUtf8("Cross stitch preview error!"));
738 return;
739 }
740
741
742 QPainter painter(&img);
743 QBrush brush(Qt::SolidPattern);
744 QPen pen(brush,ui.lineSB1->value());//Задание ширины линии
745
746 qreal pScale=scale*squarePix/view->squarePix();
747 painter.scale(pScale,pScale);
748 painter.translate(-view->dx(),-view->dx());
749
750
751 int max=20;
752 int pbdiv=(view->spriteSize()+view->lineSize())/max;
753 progressDialog pb(trUtf8("Making cross stitch"),trUtf8("Cancel"),0,max+1);
754 pb.show();
755
756
757 int offsetLeft=ui.dlSB->value();//Отступ
758 int offsetRight=squarePix-offsetLeft;
759 for(int k=0;k<view->spriteSize();k++){
760 Sprite *sp=view->getSprite(k);
761 if(pen.color()!=sp->color()){
762 pen.setColor(sp->color());
763 painter.setPen(pen);
764 }
765 int x=sp->pos().x();
766 int y=sp->pos().y();
767 switch(sp->stitch()){
768 case Sprite::Cross:{
769 painter.drawLine(x+offsetLeft, y+offsetLeft, x+offsetRight, y+offsetRight);
770 painter.drawLine(x+offsetLeft, y+offsetRight, x+offsetRight, y+offsetLeft);
771 }break;
772 case Sprite::Left:painter.drawLine(x+offsetLeft, y+offsetLeft, x+offsetRight, y+offsetRight);break;
773 case Sprite::Right:painter.drawLine(x+offsetLeft, y+offsetRight, x+offsetRight, y+offsetLeft);break;
774 }
775
776 if(k%pbdiv==0)pb.addValue(1);
777 if(pb.wasCanceled())return;
778 }
779
780
781 for(int k=0;k<view->lineSize();k++){
782 Line *ln=view->getLine(k);
783 if((pen.color()!=ln->color())||(pen.width()!=ln->width())){
784 pen.setColor(ln->color());
785 pen.setWidth(ln->width());
786 painter.setPen(pen);
787 }
788
789 painter.drawLine(ln->p1(),ln->p2());
790
791
792 if(k%pbdiv==0)pb.addValue(1);
793 if(pb.wasCanceled())return;
794 }
795
796
797 crostiViewer->setImage(img.toImage());
798
799
800 //ui.tabWidget->setCurrentIndex(3);
801
802 if(scale<1){
803 Info::messageSplash(trUtf8("Image size reduction forced!"));
804 statusBar()->showMessage(trUtf8("If you see a blank cross stitch, try different cross stitch parameters."),3e4);
805 }
806
807 _crostiName=trUtf8("new");
808 setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Cross stitch: ")+_crostiName+"]");
809 crostiSizeShow(ui.squareSB1->value());
810
811 setCurrentTab(3);
812
813 }
814
815
816
817
818
crostiSizeShow(int val)819 void MainWindow::crostiSizeShow(int val){
820 float mul=1;
821 QString unitName="";
822 switch (_units) {
823 case 0: {
824 mul = float(25.4);
825 unitName = trUtf8("mm");
826 }break;
827 case 1: {
828 mul = 1;
829 unitName = trUtf8("in");
830 }break;
831 }
832
833 float w=mul*view->schemeSize().width()/val;
834 float h=mul*view->schemeSize().height()/val;
835 infoLabel->setText(trUtf8("Cross stitch:"));
836 sizeLabel->setText(QString::number(w,'f',1)+unitName+" x "+QString::number(h,'f',1)+unitName);
837 }
838
839
schemeSizeShow()840 void MainWindow::schemeSizeShow(){
841 infoLabel->setText(trUtf8("Scheme:"));
842 sizeLabel->setText(QString::number(view->schemeSize().width())+"x"+QString::number(view->schemeSize().height())+"x"+QString::number(colorTable.size()));
843 }
844
845
imageSizeShow(QImage img)846 void MainWindow::imageSizeShow(QImage img){
847 int w=imgW;
848 int h=imgH;
849 QString depth=QString::number(colorTable.size());
850 if(!img.isNull()){
851 w=img.width();
852 h=img.height();
853 depth=QString::number(img.depth())+"b";
854 }
855 infoLabel->setText(trUtf8("Picture:"));
856 sizeLabel->setText(QString::number(w)+"x"+QString::number(h)+"x"+depth);
857 }
858
859
setSquareSBtoolTip()860 int MainWindow::setSquareSBtoolTip()
861 {
862 QImage image(Info::dataPath()+"/system/clpics/clpic0.bmp");
863 int h=image.height()+ui.lineSB->value()+dL+2*dl;
864 ui.squareSB->setToolTip(trUtf8("Set value ")+QString::number(h)+"<br>"+trUtf8("for better design aspect"));
865 return h;
866 }
867
868
isMemoryAvailable(qreal msize)869 bool MainWindow::isMemoryAvailable(qreal msize)
870 {
871 bool result=true;
872 //------------------------------------------------------------------------------
873 //Проверка возможности выделения памяти для схемы
874 //------------------------------------------------------------------------------
875 if(msize==0)msize=sizeof(Sprite)*imgW*imgH;
876 void *pt=NULL;
877 pt=malloc(msize);
878 if(pt==NULL){
879 Info::messageSplash(Info::msgOutOfMemory);
880 result=false;
881 }else free(pt);
882 //------------------------------------------------------------------------------
883 //------------------------------------------------------------------------------
884 //------------------------------------------------------------------------------
885 return result;
886 }
887
888 /*
889 void MainWindow::shrinkImageList()
890 {
891 QList<QImage>tmpImageList;
892 for(int i=0;i<id.size();i++){
893 int pos=id.at(i);
894 if((pos>NO_ICON)&&(pos<_clpicCount))
895 tmpImageList.append(imageList.at(pos));
896 }
897 imageList.clear();
898 imageList.append(tmpImageList);
899 tmpImageList.clear();
900
901 if(ui.chbInvert->isChecked())
902 for(int i=0;i<imageList.size();i++)imageList[i].invertPixels();
903 }
904 */
905
schemeFromFile(QString fileName)906 void MainWindow::schemeFromFile(QString fileName)
907 {
908
909 int squarePix=ui.squareSB->value();//Ребро клетки
910 linePix=ui.lineSB->value();
911 int dX=int(1.5*squarePix);//Отступ для нумерации
912
913 if(!isMemoryAvailable()){
914 Info::messageSplash(Info::msgOutOfMemory);
915 return;
916 }
917
918 setParameters(squarePix,linePix,dl);
919
920 int sz=imgW*imgH;
921 int max=20;
922 int pbdiv=sz/max;
923 if(sz<max)pbdiv=1;
924 progressDialog pb(trUtf8("Creating the design"),trUtf8("Cancel"),0,max+1);
925 pb.show();
926
927 view->setParameters(squarePix,imgW,imgH,dX,linePix,dl);
928 view->clear();
929
930 //shrinkImageList();
931
932 int pbcounter=0;
933 QFile file(fileName);
934 if(file.open(QIODevice::ReadOnly|QIODevice::Text)){
935 QTextStream in(&file);
936
937 QString str="";
938 while((str!="#SCHEME CONTENT")&&(!in.atEnd()))str=in.readLine();
939 in.readLine();//Читаем строку параметров схемы
940
941 while(!in.atEnd()){
942
943 str="";
944 while((str.isEmpty())&&(!in.atEnd()))str=in.readLine();
945
946 QStringList strList=str.split(" ");
947 bool isOk=true;
948 if((strList.size()==3)||(strList.size()==4)){
949 int x=strList.at(0).toInt(&isOk);
950 if(!isOk)break;
951 int y=strList.at(1).toInt(&isOk);
952 if(!isOk)break;
953 x=dX+squarePix*x;
954 y=dX+squarePix*y;
955 int index=strList.at(2).toInt(&isOk);
956 if(!isOk)break;
957
958 QColor cl=_bkColor;
959 if(index>=0){
960 if(index<colorTable.size())cl=colorTable.at(index);
961 if(index<_clpicCount)index=id.at(index);
962 }else index=INT_MAX;
963 //Цвет = _bkColor и iconID = INT_MAX определяют цвет фона.
964 view->createSprite(QPoint(x,y),cl,index);
965
966 if(strList.size()==4){
967 int stId=strList.at(3).toInt(&isOk);
968 if(!isOk)break;
969 Sprite::Stitch stitch=static_cast<Sprite::Stitch>(stId);
970 view->getSprite(view->spriteSize()-1)->setStitch(stitch);
971 }
972
973 pbcounter++;
974 if(pbcounter==pbdiv){
975 pb.addValue(1);
976 pbcounter=0;
977 }
978 if(pb.wasCanceled())return;
979 }
980
981 if(strList.size()==6){
982 int x1=strList.at(0).toInt(&isOk);
983 if(!isOk)break;
984 int y1=strList.at(1).toInt(&isOk);
985 if(!isOk)break;
986 int x2=strList.at(2).toInt(&isOk);
987 if(!isOk)break;
988 int y2=strList.at(3).toInt(&isOk);
989 if(!isOk)break;
990 int w=strList.at(4).toInt(&isOk);
991 if(!isOk)break;
992 int index=strList.at(5).toInt(&isOk);
993 if(!isOk)break;
994 QColor cl=Qt::black;
995 if(index<colorTable.size())cl=colorTable.at(index);
996 view->createLine(QPoint(x1,y1),QPoint(x2,y2),cl,w);
997 }
998
999 }
1000 file.close();
1001 }
1002 if(view->spriteSize()==0)Info::messageSplash(trUtf8("Scheme contains no data!"));
1003
1004 }
1005
1006
1007
spriteFromImage(QImage image)1008 void MainWindow::spriteFromImage(QImage image)
1009 {
1010 int squarePix=ui.squareSB->value();//Ребро клетки
1011 linePix=ui.lineSB->value();
1012 int dX=int(1.5*squarePix);//Отступ для нумерации
1013
1014 if(!isMemoryAvailable()){
1015 Info::messageSplash(Info::msgOutOfMemory);
1016 return;
1017 }
1018
1019 setParameters(squarePix,linePix,dl);
1020
1021 int sz=imgW*imgH;
1022 int max=20;
1023 int pbdiv=sz/max;
1024 if(sz<max)pbdiv=1;
1025 progressDialog pb(trUtf8("Creating the design"),trUtf8("Cancel"),0,max+1);
1026 pb.show();
1027
1028 //---
1029 view->setParameters(squarePix,imgW,imgH,dX,linePix,dl);
1030 view->clear();
1031
1032 QList<int>bkID;
1033 //---Создание новой схемы
1034 for(int i=0;i<_clpicCount;i++)bkID.append(i);
1035
1036 //---Случайное перемешивание пиктограмм цветов (для возможного улучшения читаемости)
1037 for(int i=0;i<int(bkID.size()/2);i++){
1038 int k=int(random(bkID.size()-1));
1039 bkID.swap(i,k);
1040 }
1041
1042 if(ui.chbInvert->isChecked())
1043 for(int i=0;i<imageList.size();i++)imageList[i].invertPixels();
1044
1045
1046 int pbcounter=0;
1047 QList<QRgb>::const_iterator ctit,ctitEnd,ctitBegin;
1048 ctitEnd=colorTable.end();
1049 ctitBegin=colorTable.begin();
1050
1051 QMap<int,int> index;
1052
1053 //Переделываем схему из рисунка
1054 for(int i=0;i<image.width();i++){
1055 int x=dX+squarePix*i;
1056 for(int j=0;j<image.height();j++){
1057
1058 int y=dX+squarePix*j;
1059
1060 ctit=qFind(colorTable,image.pixel(i,j));
1061
1062 if(ctit!=ctitEnd){
1063
1064 int ik=ctit-ctitBegin;
1065 int iconID=ik;
1066 if(ik<_clpicCount)iconID=bkID.at(ik);
1067
1068 index.insert(ik,iconID);
1069
1070 if(!view->createSprite(QPoint(x,y),*ctit,iconID)){
1071 view->clear();
1072 Info::messageSplash(Info::msgOutOfMemory);
1073 return;
1074 }
1075
1076
1077 pbcounter++;
1078
1079 if(pbcounter==pbdiv){
1080 pb.addValue(1);
1081
1082 pbcounter=0;
1083 }
1084 if(pb.wasCanceled()){
1085 view->clear();
1086 return;
1087 }
1088
1089 }
1090
1091 }
1092 }
1093
1094 id.clear();
1095 QMapIterator<int,int>i(index);
1096 while(i.hasNext()){
1097 i.next();
1098 id.append(i.value());
1099 }
1100
1101 _isSchemeUpdated=false;
1102 }
1103
1104
1105
spriteFromView(int square)1106 void MainWindow::spriteFromView(int square)
1107 {
1108
1109 int squarePix=square;//Ребро клетки
1110 linePix=ui.lineSB->value();
1111 int dX=int(1.5*squarePix);//Отступ для нумерации
1112
1113 if(!isMemoryAvailable()){
1114 Info::messageSplash(Info::msgOutOfMemory);
1115 return;
1116 }
1117
1118 setParameters(squarePix,linePix,dl);
1119
1120 //shrinkImageList();
1121
1122
1123 //Переделываем схему загруженную из файла
1124 QList<QRgb>::const_iterator ctit,ctitEnd,ctitBegin;
1125 ctitEnd=colorTable.end();
1126 ctitBegin=colorTable.begin();
1127
1128 for(int i=0;i<view->spriteSize();i++){
1129 Sprite *sp=view->getSprite(i);
1130 if(sp!=NULL){
1131 int x=dX+int((sp->pos().x()-view->dx())/view->squarePix())*squarePix;
1132 int y=dX+int((sp->pos().y()-view->dx())/view->squarePix())*squarePix;
1133 sp->setPos(QPoint(x,y));
1134
1135 ctit=qFind(colorTable,sp->color().rgb());
1136 if(ctit!=ctitEnd){
1137 int ik=ctit-ctitBegin;
1138 if(ik<_clpicCount)ik=id.at(ik);
1139 sp->setIconID(ik);
1140 }
1141 }
1142 }
1143
1144
1145 QPoint dx(view->dx(),view->dx());
1146 QPoint DX(dX,dX);
1147 for(int i=0;i<view->lineSize();i++){
1148 Line *ln=view->getLine(i);
1149 if(ln!=NULL)
1150 ln->setPoints(DX+squarePix*(ln->p1()-dx)/view->squarePix(),DX+squarePix*(ln->p2()-dx)/view->squarePix());
1151 }
1152
1153 view->setParameters(squarePix,imgW,imgH,dX,linePix,dl);
1154 }
1155
1156
setParameters(int squarePix,int linePix,int dl)1157 void MainWindow::setParameters(int squarePix,int linePix,int dl)
1158 {
1159 QFont font=_mainFontHalf;
1160
1161 const int FONT_POINT_SIZE_MIN = 6;
1162 const int FONT_POINT_SIZE = (squarePix - 2 * dl) / 2;
1163
1164 font.setPointSize((FONT_POINT_SIZE < FONT_POINT_SIZE_MIN) ?
1165 FONT_POINT_SIZE_MIN :
1166 FONT_POINT_SIZE);
1167
1168 QBrush brush(Qt::SolidPattern);
1169 QPen pen(brush,linePix);
1170 if(ui.chbInvert->isChecked())pen.setColor(Qt::white);
1171 view->setPen(pen);
1172 view->setFont(font);
1173
1174 imageList.clear();
1175 setClPicCount();
1176 setImageList(squarePix,dl);
1177 view->setClPicCount(_clpicCount);
1178 view->setImageList(imageList);
1179 }
1180
1181
schemeCreate()1182 void MainWindow::schemeCreate()
1183 {
1184 int squarePix=ui.squareSB->value();//Ребро клетки
1185
1186 if(view->spriteSize()!=0){
1187 //---Заполняем таблицу пиктограмм цветов
1188 disconnect(paletteModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(schemeModify(QStandardItem*)));
1189 paletteModel->setRowCount(0);
1190 delegate->setSize(squarePix-2*dl,squarePix-2*dl);
1191 for(int ik=0;ik<colorTable.size();ik++){
1192 int rc=paletteModel->rowCount();
1193 paletteModel->insertRows(rc, 1);
1194
1195 QString text="";
1196 for(int k=0;k<palette.color.size();k++){
1197 if(palette.color.at(k)._value==colorTable.at(ik)){
1198 text=palette.color.at(k)._number+" "+palette.color.at(k)._description;
1199 break;
1200 }
1201 }
1202 QModelIndex parent=paletteModel->index(rc,0,QModelIndex());
1203 paletteModel->setData(parent,text,Qt::DisplayRole);
1204 paletteModel->setData(parent,QColor(colorTable.at(ik)),Qt::DecorationRole);
1205 paletteModel->setData(parent,colorTable.at(ik),Qt::UserRole);//Заносим дополнительную информацию о цвете для удобного поиска в schemeModify
1206
1207 QModelIndex parent1=paletteModel->index(rc,1);
1208 if(ik<_clpicCount){
1209 const int ID = id.value(ik, Sprite::NO_ICON);
1210 QImage image = imageList.value(ID);
1211 if (ui.chbInvert->isChecked())
1212 image.invertPixels();
1213 paletteModel->setData(parent1,QIcon(QPixmap::fromImage(image)),Qt::DecorationRole);
1214 paletteModel->setData(parent1,ID,Qt::UserRole);//Заносим дополнительную информацию об идентификаторе иконки для использования в createEditor
1215 }else{
1216 text=Info::colorSign(ik);
1217 paletteModel->setData(parent1,text,Qt::DisplayRole);
1218 paletteModel->setData(parent1,ik,Qt::UserRole);
1219 }
1220
1221 }
1222 ui.tvPalette->resizeColumnToContents(0);
1223 ui.tvPalette->resizeColumnToContents(1);
1224
1225 connect(paletteModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(schemeModify(QStandardItem*)));
1226 //-----------------------------------------------------------------------------
1227
1228
1229
1230 schemeViewer->reset();
1231
1232
1233
1234 if(ui.chbInvert->isChecked())
1235 for(int i=0;i<imageList.size();i++)imageList[i].invertPixels();
1236
1237
1238 _isSchemeCreated=true;
1239 schemeSizeShow();
1240
1241
1242 colorTableCreate();
1243
1244 square=ui.squareSB->value();
1245 ui.dwPalette->setEnabled(true);
1246 ui.dwTool->setEnabled(true);
1247 ui.dwCrosti->setEnabled(true);
1248
1249
1250 //ui.tabWidget->setCurrentIndex(1);
1251 setCurrentTab(1);
1252 }
1253 }
1254
1255
1256
colorUpdate(int row,QColor color)1257 void MainWindow::colorUpdate(int row,QColor color)
1258 {
1259
1260 uint errorRow=0;
1261 bool isError=false;
1262 for(int i=0;i<paletteModel->rowCount();i++){
1263 QModelIndex parent=paletteModel->index(i,0,QModelIndex());
1264 QRgb cl=paletteModel->data(parent,Qt::UserRole).toUInt();
1265 if(cl==color.rgba()){
1266 Info::messageSplash(trUtf8("Palette conflict, row %1 cleared.").arg(i+1));
1267 errorRow=i;
1268 isError=true;
1269 }
1270 }
1271
1272
1273 disconnect(paletteModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(schemeModify(QStandardItem*)));
1274
1275 QString text="";
1276 for(int k=0;k<palette.color.size();k++){
1277 if(palette.color.at(k)._value==color.rgba()){
1278 text=palette.color.at(k)._number+" "+palette.color.at(k)._description;
1279 break;
1280 }
1281 }
1282
1283 QModelIndex parent=paletteModel->index(row,0,QModelIndex());
1284 paletteModel->setData(parent,text,Qt::DisplayRole);
1285 paletteModel->setData(parent,color,Qt::DecorationRole);
1286 paletteModel->setData(parent,color.rgba(),Qt::UserRole);//Заносим дополнительную информацию о цвете для удобного поиска в schemeModify
1287
1288
1289 colorTable.replace(row,color.rgba());
1290
1291
1292 if(isError)clearColor(errorRow);
1293
1294 setColor(row);
1295
1296 connect(paletteModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(schemeModify(QStandardItem*)));
1297 }
1298
1299
1300
iconUpdate(int row,int iid)1301 void MainWindow::iconUpdate(int row,int iid)
1302 {
1303
1304 uint errorRow=0;
1305 bool isError=false;
1306 for(int i=0;i<paletteModel->rowCount();i++){
1307 QModelIndex parent=paletteModel->index(i,1,QModelIndex());
1308 int id=paletteModel->data(parent,Qt::UserRole).toInt();
1309 if(id==iid){
1310 Info::messageSplash(trUtf8("Palette conflict, row %1 cleared.").arg(i+1));
1311 errorRow=i;
1312 isError=true;
1313 }
1314 }
1315
1316 disconnect(paletteModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(schemeModify(QStandardItem*)));
1317
1318
1319 QModelIndex parent1=paletteModel->index(row,1);
1320 if((iid>=0)&&(iid<_clpicCount)){
1321 QImage image(Info::dataPath()+"/system/clpics/clpic"+QString::number(iid)+".bmp");
1322 image=image.scaled(square-2*dl,square-2*dl);
1323 image.setAlphaChannel(image.createMaskFromColor(0xFFFFFFFF,Qt::MaskOutColor));
1324
1325 if(ui.chbInvert->isChecked())image.invertPixels();
1326 paletteModel->setData(parent1,QIcon(QPixmap::fromImage(image)),Qt::DecorationRole);
1327 paletteModel->setData(parent1,iid,Qt::UserRole);//Заносим дополнительную информацию об идентификаторе иконки для использования в createEditor
1328 }
1329
1330 if(isError)clearColor(errorRow);
1331
1332 setColor(row);
1333
1334 connect(paletteModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(schemeModify(QStandardItem*)));
1335 }
1336
1337
addColorBtnPress()1338 void MainWindow::addColorBtnPress()
1339 {
1340 addColor(paletteModel->rowCount(),Qt::transparent);
1341 }
1342
1343
clearColor(int row)1344 void MainWindow::clearColor(int row)
1345 {
1346 QRgb rgbcl=Qt::transparent;
1347 QModelIndex parent=paletteModel->index(row,0,QModelIndex());
1348 paletteModel->setData(parent,"",Qt::DisplayRole);
1349 paletteModel->setData(parent,QColor(rgbcl),Qt::DecorationRole);
1350 paletteModel->setData(parent,rgbcl,Qt::UserRole);
1351
1352 parent=paletteModel->index(row,1,QModelIndex());
1353 paletteModel->setData(parent,Sprite::NO_ICON,Qt::UserRole);
1354 paletteModel->setData(parent,QIcon(),Qt::DecorationRole);
1355 }
1356
1357
addColor(int row,QRgb rgbcl)1358 void MainWindow::addColor(int row,QRgb rgbcl)
1359 {
1360 disconnect(paletteModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(schemeModify(QStandardItem*)));
1361 paletteModel->insertRows(row,1);
1362
1363 colorTable.append(rgbcl);
1364 QModelIndex parent=paletteModel->index(row,0,QModelIndex());
1365 paletteModel->setData(parent,QColor(rgbcl),Qt::DecorationRole);
1366 paletteModel->setData(parent,rgbcl,Qt::UserRole);//Заносим дополнительную информацию о цвете для удобного поиска в schemeModify
1367
1368
1369 QModelIndex parent1=paletteModel->index(row,1);
1370
1371
1372 if(row<_clpicCount){
1373 id.append(Sprite::NO_ICON);
1374 paletteModel->setData(parent1,Sprite::NO_ICON,Qt::UserRole);
1375 }else{
1376 QString text=Info::colorSign(row);
1377 paletteModel->setData(parent1,text,Qt::DisplayRole);
1378 paletteModel->setData(parent1,row,Qt::UserRole);
1379 }
1380
1381 sizeLabel->setText(QString::number(imgW)+"x"+QString::number(imgH)+"x"+QString::number(colorTable.size()));
1382
1383 connect(paletteModel,SIGNAL(itemChanged(QStandardItem*)),this,SLOT(schemeModify(QStandardItem*)));
1384 }
1385
1386
1387
removeColorBtnPress()1388 void MainWindow::removeColorBtnPress()
1389 {
1390 QModelIndexList mil=ui.tvPalette->selectionModel()->selectedRows();
1391
1392 for(int i=0;i<mil.size();i++){
1393 /*
1394 QRgb rgbcl=QRgb(paletteModel->data(mil.at(i),Qt::UserRole).toUInt());
1395 int row=mil.at(i).row();
1396 int count=view->colorCount(rgbcl);
1397 if(count==0){
1398
1399 removeColor(row,rgbcl);
1400 setColor(0);
1401
1402 }else Info::messageSplash(trUtf8("Can't remove -")+
1403 trUtf8(" scheme contains selected color %1 times").arg(count));
1404 */
1405
1406
1407 int ret=QMessageBox::question(this,QApplication::applicationName(),
1408 trUtf8("Delete color from palette (it can not be undone)?"),
1409 QMessageBox::Yes | QMessageBox::No,
1410 QMessageBox::No);
1411 switch(ret){
1412 case QMessageBox::Yes:{
1413 QRgb rgbcl=QRgb(paletteModel->data(mil.at(i),Qt::UserRole).toUInt());
1414 int row=mil.at(i).row();
1415 removeColor(row,rgbcl);
1416 setColor(0);
1417 }
1418 break;
1419
1420 case QMessageBox::No:
1421 break;
1422 }
1423
1424 }
1425 }
1426
1427
removeColor(int row,QRgb rgbcl)1428 void MainWindow::removeColor(int row,QRgb rgbcl){
1429 colorTable.removeAt(colorTable.indexOf(rgbcl));
1430 id.removeAt(row);
1431 paletteModel->removeRow(row);
1432
1433 view->history.remove(rgbcl);
1434 view->swapColorToBackground(rgbcl);
1435
1436 sizeLabel->setText(QString::number(imgW)+"x"+QString::number(imgH)+"x"+QString::number(colorTable.size()));
1437 _isColorTableUpdated=true;
1438 if(ui.tabWidget->currentIndex()==2)colorTableCreate(true);
1439 }
1440
1441
squareChanged(int square)1442 void MainWindow::squareChanged(int square)
1443 {
1444 spriteFromView(square);
1445 schemeCreate();
1446 }
1447
1448
schemeSaveDialog()1449 bool MainWindow::schemeSaveDialog()
1450 {
1451 bool proceed=true;
1452 if(_isSchemeUpdated){
1453 int ret=QMessageBox::question(this,QApplication::applicationName(),
1454 trUtf8("Scheme has changed. Save before proceeding?"),
1455 QMessageBox::Yes | QMessageBox::No
1456 | QMessageBox::Cancel,
1457 QMessageBox::Yes);
1458 switch(ret){
1459 case QMessageBox::Yes:if(saveSchemeDialog()==QDialog::Rejected)proceed=false;
1460 break;
1461 case QMessageBox::No:
1462 break;
1463 case QMessageBox::Cancel:proceed=false;
1464 break;
1465 }
1466 }
1467 return proceed;
1468 }
1469
1470
1471
paletteOpen(const QString & name)1472 void MainWindow::paletteOpen(const QString &name)
1473 {
1474 palette.open(name);
1475 ui.dwPalette->setWindowTitle(trUtf8("Palette") + ": " + name);
1476 ui.dwPalette->setProperty("paletteName", name);
1477 }
1478
1479
1480
schemeBtnPress()1481 void MainWindow::schemeBtnPress()
1482 {
1483 if(schemeSaveDialog()){
1484 paletteOpen(ColorPalette::name());
1485
1486 _schemeData* schemedata=getSchemeData();
1487
1488 makeScheme(schemedata);
1489
1490 delete schemedata;
1491 }
1492
1493 }
1494
1495
makeScheme(_schemeData * schemedata)1496 void MainWindow::makeScheme(_schemeData *schemedata){
1497 if(!schemedata->isNull()){
1498
1499 colorCount.clear();
1500 colorTable.clear();
1501 colorTable.append(schemedata->clT());
1502
1503 crostiViewer->scene()->clear();
1504
1505 showImage(schemedata->image());
1506 //ui.tabWidget->setCurrentIndex(0);
1507 setSquareSBtoolTip();
1508 _isConverted=true;
1509 spriteFromImage(schemedata->image());
1510
1511 //Убираем цвета с нулевым присутствием
1512 int ctsize=colorTable.size();
1513 int i=0;
1514 while(i<colorTable.size()){
1515 int count=view->colorCount(colorTable.at(i));
1516 if(count==0){
1517 colorTable.removeAt(i);
1518 }else i++;
1519 }
1520
1521 if(colorTable.size()<ctsize)
1522 Info::message(trUtf8("Impossible to convert or find all colors!")+"<br>"+
1523 trUtf8("Palette set to ")+QString::number(colorTable.size())+
1524 trUtf8(" colors."));
1525 //------------------------------------------------------------------------------
1526
1527 schemeCreate();
1528
1529 _schemeName=trUtf8("new");
1530 setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Scheme: ")+_schemeName+"]");
1531 }
1532 }
1533
1534
1535
1536
updateTab(int index)1537 void MainWindow::updateTab(int index)
1538 {
1539
1540 imageViewer->disconnectViewPortWatcher();
1541 schemeViewer->disconnectViewPortWatcher();
1542 crostiViewer->disconnectViewPortWatcher();
1543 colorViewer->disconnectViewPortWatcher();
1544
1545
1546 QString mod = _isSchemeUpdated ? "*" : "";
1547
1548 switch(index){
1549 case 0:{if(_isConverted)imageSizeShow();else imageSizeShow(_image);
1550 if(_imageName!="")setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Picture: ")+_imageName+"]");
1551 else setWindowTitle(QApplication::applicationName());
1552
1553 if (ui.dwMiniMap->isVisible()) {
1554 //imageViewer->disconnectViewPortWatcher();
1555 MiniMap->setViewPortColor(MiniMapRectColor);
1556 imageViewer->updateMiniMap();
1557 }
1558
1559 }break;
1560 case 1:{schemeSizeShow();
1561 if(_schemeName!="")setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Scheme: ")+_schemeName+"] "+mod);
1562 else setWindowTitle(QApplication::applicationName());
1563
1564 if (ui.dwMiniMap->isVisible()) {
1565 //schemeViewer->disconnectViewPortWatcher();
1566 MiniMap->setViewPortColor(MiniMapRectColor);
1567 schemeViewer->updateMiniMap();
1568 }
1569
1570 }break;
1571 case 2:{
1572 if(_schemeName!="")
1573 setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Scheme: ")+_schemeName+"] "+mod);
1574 else setWindowTitle(QApplication::applicationName());
1575
1576 if(_isColorTableUpdated){
1577 colorTableCreate(true);
1578 _isColorTableUpdated=false;
1579 }
1580
1581 infoLabel->setText(trUtf8("Palette:"));
1582 sizeLabel->setText(ui.dwPalette->property("paletteName").toString() + ", " + QString::number(colorTable.size()));
1583
1584
1585 if (ui.dwMiniMap->isVisible()) {
1586 //colorViewer->disconnectViewPortWatcher();
1587 MiniMap->setViewPortColor(Qt::black);
1588 colorViewer->updateMiniMap();
1589 }
1590
1591 }break;
1592 case 3:{crostiSizeShow(ui.squareSB1->value());
1593 if(!_crostiName.isEmpty())setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Cross stitch: ")+_crostiName+"]");
1594 else setWindowTitle(QApplication::applicationName());
1595
1596 if (ui.dwMiniMap->isVisible()) {
1597 //crostiViewer->disconnectViewPortWatcher();
1598 MiniMap->setViewPortColor(View::invertColor(_bkColor));
1599 crostiViewer->updateMiniMap();
1600 }
1601
1602 }break;
1603 }
1604 }
1605
1606
colorTableCreate(bool update)1607 void MainWindow::colorTableCreate(bool update)
1608 {
1609 int clWtext=300; //Длина текстового блока
1610 int clWtextSign=20; //Длина текстового блока обозначения цвета
1611 int clWcolor=30; //Длина цветового блока
1612 int clH=30; //Высота строк
1613 int spacing=10; //Расстояние между строками и блоками
1614 int spacing1=50; //Расстояние между столбцами
1615 int headerH = clH + spacing;
1616
1617
1618 int squarePix=ui.squareSB->value();
1619
1620 clWcolor=2*squarePix;
1621 if(squarePix>clH)clH=squarePix;
1622
1623 linePix=ui.lineSB->value();
1624 lineBoldPix=linePix+dL;
1625
1626
1627
1628 int height=(int(colorTable.size()/2)+colorTable.size()%2)*(clH+spacing)+spacing + headerH;
1629 QPixmap pix(2*(clWtext+clWcolor)+4*spacing+spacing1,height);
1630 pix.fill(Qt::white);
1631
1632 QPainter painter;
1633 painter.begin(&pix);
1634
1635 painter.setPen(Qt::black);
1636
1637 painter.setFont(_mainFontBold);
1638 painter.drawText(spacing, painter.fontMetrics().height(),
1639 ui.dwPalette->property("paletteName").toString() + ", " +
1640 QString::number(colorTable.size()));
1641
1642 painter.setFont(_mainFont);
1643
1644 for(int i=0;i<colorTable.size();i++){
1645 QImage image,imageI;
1646 QString text,textSign;
1647
1648 if(_isSchemeCreated){
1649 if(i<_clpicCount){
1650 if(!update){
1651 image = imageList.value(id.value(i, Sprite::NO_ICON));
1652 }else{
1653 image.load(Info::dataPath()+"/system/clpics/clpic"+QString::number(id.at(i))+".bmp");
1654 image=image.scaled(squarePix-2*dl,squarePix-2*dl);
1655 image.setAlphaChannel(image.createMaskFromColor(0xFFFFFFFF,Qt::MaskOutColor));
1656 }
1657 imageI=image;
1658 if(ui.chbInvert->isChecked())imageI.invertPixels();
1659 }else textSign=Info::colorSign(i);
1660 }
1661
1662 QPixmap pixmap(clWcolor,clH);
1663 pixmap.fill(colorTable.at(i));
1664
1665 int count=view->colorCount(colorTable.at(i));
1666
1667
1668
1669 for(int k=0;k<palette.color.size();k++){
1670 if(palette.color.at(k)._value==colorTable.at(i)){
1671 text=": "+palette.color.at(k)._number+" "+palette.color.at(k)._description;
1672 break;
1673 }
1674 }
1675
1676 text+=" ("+QString::number(count)+")";
1677
1678
1679 int dx=0;
1680 if(image.width()>clWtextSign)dx=image.width();
1681 else dx=clWtextSign;
1682
1683 if(i<colorTable.size()/2+colorTable.size()%2){
1684 painter.drawPixmap(2*spacing+dx,spacing+i*(spacing+clH) + headerH, pixmap);
1685
1686 if(i<_clpicCount){
1687 painter.drawImage(spacing, spacing+i*(spacing+clH) + headerH, image);
1688 painter.drawImage(2*spacing+dx+dl,spacing+i*(spacing+clH)+dl + headerH,imageI);
1689 }else{
1690 painter.drawText(QRect(spacing,spacing+i*(spacing+clH) + headerH,clWtextSign,clH),Qt::AlignLeft,textSign);
1691 if(ui.chbInvert->isChecked())painter.setPen(Qt::white);
1692 painter.drawText(QRect(2*spacing+dx,spacing+i*(spacing+clH) + headerH,clWtextSign,clH),Qt::AlignLeft,textSign);
1693 }
1694 painter.setPen(Qt::black);
1695 painter.drawText(QRect(3*spacing+dx+clWcolor,spacing+i*(spacing+clH) + headerH,clWtext+clWtextSign-image.width(),clH),Qt::AlignLeft,text);
1696 }else{
1697 painter.drawPixmap(spacing1+3*spacing+dx+clWtext+clWcolor,spacing+int(i-colorTable.size()/2-colorTable.size()%2)*(spacing+clH) + headerH, pixmap);
1698
1699 if(i<_clpicCount){
1700 painter.drawImage(spacing1+2*spacing+clWtext+clWcolor,spacing+int(i-colorTable.size()/2-colorTable.size()%2)*(spacing+clH) + headerH, image);
1701 painter.drawImage(spacing1+3*spacing+dx+clWtext+clWcolor+dl,spacing+int(i-colorTable.size()/2-colorTable.size()%2)*(spacing+clH)+dl + headerH, imageI);
1702 }else{
1703 painter.drawText(QRect(spacing1+2*spacing+clWtext+clWcolor,spacing+int(i-colorTable.size()/2-colorTable.size()%2)*(spacing+clH) + headerH, clWtext,clH),Qt::AlignLeft,textSign);
1704 if(ui.chbInvert->isChecked())painter.setPen(Qt::white);
1705 painter.drawText(QRect(spacing1+3*spacing+dx+clWtext+clWcolor,spacing+int(i-colorTable.size()/2-colorTable.size()%2)*(spacing+clH) + headerH, clWtext,clH),Qt::AlignLeft,textSign);
1706 }
1707 painter.setPen(Qt::black);
1708 painter.drawText(QRect(spacing1+4*spacing+dx+clWtext+2*clWcolor,spacing+int(i-colorTable.size()/2-colorTable.size()%2)*(spacing+clH) + headerH, clWtext-image.width(),clH),Qt::AlignLeft,text);
1709 }
1710 }
1711
1712 painter.end();
1713
1714
1715 colorViewer->setImage(pix.toImage());
1716
1717 }
1718
1719
1720
1721
1722
getSchemeData()1723 _schemeData* MainWindow::getSchemeData()
1724 {
1725 Qt::AspectRatioMode aspectRatio=Qt::IgnoreAspectRatio;
1726 if(ui.aspectChb->isChecked())aspectRatio=Qt::KeepAspectRatioByExpanding;
1727
1728 QImage image=_image;
1729 QSize sz=_image.size();
1730
1731 if(ui.rbc->isChecked())sz=QSize(ui.widthSB->value(),ui.heightSB->value());
1732 if(ui.rbx14->isChecked())sz=QSize(_image.width()/4,_image.height()/4);
1733 if(ui.rbx12->isChecked())sz=QSize(_image.width()/2,_image.height()/2);
1734 if(ui.rbx2->isChecked())sz=QSize(_image.width()*2,_image.height()*2);
1735 if(ui.rbx4->isChecked())sz=QSize(_image.width()*4,_image.height()*4);
1736
1737 image=_image.scaled(sz,aspectRatio,Qt::SmoothTransformation);
1738
1739 _schemeData* schemedata=new _schemeData(image);
1740
1741 schemedata->convert(palette,ui.colorSB->value(),ui.filterCb->currentIndex());
1742
1743 return schemedata;
1744 }
1745
1746
1747 /*
1748 QPixmap MainWindow::renderPixmap(QGraphicsScene *scene)
1749 {
1750 QRectF sceneRect(scene->itemsBoundingRect());
1751 QPixmap pix(int(sceneRect.width()),int(sceneRect.height()));
1752 QPainter painter(&pix);
1753 scene->render(&painter);
1754 return pix;
1755 }
1756 */
1757
1758
preview()1759 void MainWindow::preview()
1760 {
1761 statusBar()->showMessage(Info::message(Info::msgPleaseWait));
1762 QImage image;
1763 switch(ui.tabWidget->currentIndex()){
1764 case 0:
1765 image=imageViewer->image();break;
1766 case 1:
1767 image=view->toImage(true);break;
1768 case 2:
1769 image=colorViewer->image();break;
1770 case 3:
1771 image=crostiViewer->image();break;
1772 }
1773 QSize size=image.size()*scaleToDesktop(image.size());
1774 image=image.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation);
1775 lbPreview->showImage(image);
1776 statusBar()->clearMessage();
1777 }
1778
1779
1780
previewBtnPress()1781 void MainWindow::previewBtnPress()
1782 {
1783 _schemeData* schemedata=getSchemeData();
1784
1785 CImageViewer *viewWindow=new CImageViewer(schemedata, NULL);
1786 viewWindow->setWindowIcon(QIcon(Info::dataPath()+"/system/image/eye.png"));
1787 connect(viewWindow,SIGNAL(makeScheme(_schemeData*)),this,SLOT(makeScheme(_schemeData*)));
1788
1789 QImage img = viewWindow->image();
1790 int h = img.height();
1791 int w = img.width();
1792 viewWindow->setWindowTitle(trUtf8("Preview - [") +
1793 QString::number(w) + "x" +
1794 QString::number(h) + "x" +
1795 QString::number(img.colorCount()) + " " +
1796 ui.filterCb->currentText() + "]");
1797
1798 if (h < 300) h = 300;
1799 if (w < 300) w = 300;
1800
1801 if (h > 450) h = 450;
1802 if (w > 450) w = 450;
1803
1804 viewWindow->setGeometry(40,80,w+40,h+90);
1805 viewWindow->show();
1806 }
1807
1808
setMiniMapRectColor()1809 void MainWindow::setMiniMapRectColor()
1810 {
1811 QColor color = QColorDialog::getColor(MiniMapRectColor, this);
1812 if (color.isValid()) {
1813 MiniMapRectColor = color;
1814
1815 QSettings settings(QApplication::organizationName(),QApplication::applicationName());
1816 settings.setValue("miniMapRectColor", MiniMapRectColor);
1817
1818 setLabelColor(uiprogramsettings.lbMiniMapRect, MiniMapRectColor);
1819 }
1820 programsettingsWindow->raise();
1821 uiprogramsettings.lbStatus->setText(Info::message(Info::msgRestart));
1822 }
1823
1824
setMainFont()1825 void MainWindow::setMainFont(){
1826 bool ok;
1827 _mainFont=QFontDialog::getFont(&ok,_mainFont,this);
1828 if(ok){
1829 if (_mainFont.pointSize() > 24)
1830 _mainFont.setPointSize(24);
1831
1832 QSettings settings(QApplication::organizationName(),QApplication::applicationName());
1833 settings.setValue("font/mainfont",_mainFont);
1834 QStringList mflist=_mainFont.toString().split(",",QString::SkipEmptyParts);
1835 uiprogramsettings.lbMainFontInfo->setText(trUtf8(" Font: ")+mflist.at(0)+trUtf8(" Size: ")+mflist.at(1));
1836 }
1837 programsettingsWindow->raise();
1838 uiprogramsettings.lbStatus->setText(Info::message(Info::msgRestart));
1839 }
1840
1841
1842
setTheme(QString name)1843 void MainWindow::setTheme(QString name)
1844 {
1845 QSettings rsettings(QApplication::organizationName(), QApplication::applicationName());
1846 rsettings.setValue("theme", name);
1847 uiprogramsettings.lbStatus->setText(Info::message(Info::msgRestart));
1848 }
1849
1850
1851
viewProgramSettings()1852 void MainWindow::viewProgramSettings()
1853 {
1854 if (programsettingsWindow != NULL)
1855 delete programsettingsWindow;
1856
1857 programsettingsWindow=new QDialog();
1858 programsettingsWindow->setWindowFlags(Qt::Dialog|Qt::MSWindowsFixedSizeDialogHint);
1859
1860 uiprogramsettings.setupUi(programsettingsWindow);
1861
1862 programsettingsWindow->setFont(_mainFont);
1863 programsettingsWindow->setWindowIcon(QIcon(Info::dataPath()+"/system/image/settings.png"));
1864 programsettingsWindow->setWindowTitle(QApplication::applicationName()+" - "+trUtf8("Settings"));
1865 programsettingsWindow->setStyleSheet(Theme::currentTheme().widgetStyle());
1866
1867 uiprogramsettings.cbStyle->insertItems(0, QStyleFactory::keys());
1868 uiprogramsettings.cbUnits->setCurrentIndex(_units);
1869 connect(uiprogramsettings.cbUnits,SIGNAL(activated(int)),SLOT(setUnits(int)));
1870 uiprogramsettings.cbUnits->setMinimumContentsLength(6);
1871 uiprogramsettings.cbUnits->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
1872
1873 uiprogramsettings.cbStyle->setMinimumContentsLength(6);
1874 uiprogramsettings.cbStyle->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
1875
1876 uiprogramsettings.cbTheme->setMinimumContentsLength(6);
1877 uiprogramsettings.cbTheme->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
1878 QDir dir(Info::dataPath()+"/system/theme");
1879 if(dir.exists()){
1880 QStringList list=dir.entryList(QDir::Dirs);
1881 QStringList list1;
1882 list1<<"default";
1883 for(int i=0;i<list.size();i++){
1884 QString name=list.at(i);
1885 if((name!=".")&&(name!="..")&&(name!="default"))list1<<name;
1886 }
1887 uiprogramsettings.cbTheme->addItems(list1);
1888 }
1889
1890
1891 uiprogramsettings.cbLanguage->setMinimumContentsLength(6);
1892 uiprogramsettings.cbLanguage->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
1893 dir.setPath(Info::dataPath()+"/system/translations");
1894 if(dir.exists()){
1895 QStringList list=dir.entryList(QDir::Files);
1896 uiprogramsettings.cbLanguage->addItem("en");
1897 for(int i=0;i<list.size();i++)
1898 if((list.at(i).contains("crosti_")&&(list.at(i).contains(".qm")))){
1899 QString lang=list.at(i).mid(7);
1900 lang.chop(3);
1901 uiprogramsettings.cbLanguage->addItem(lang);
1902 if(lang==_language)uiprogramsettings.cbLanguage->setCurrentIndex(uiprogramsettings.cbLanguage->count()-1);
1903 }
1904 }
1905 connect(uiprogramsettings.cbLanguage,SIGNAL(activated(QString)),SLOT(setLanguage(QString)));
1906
1907
1908
1909 uiprogramsettings.cbPalette->setMinimumContentsLength(6);
1910 uiprogramsettings.cbPalette->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
1911 dir.setPath(Info::dataPath()+"/system/palette");
1912 if(dir.exists()){
1913 QStringList list = dir.entryList(QDir::Files);
1914 foreach (QString name, list) {
1915 QString paletteName(name);
1916 paletteName.chop(4);
1917 uiprogramsettings.cbPalette->addItem(paletteName);
1918 if (paletteName == ColorPalette::name())
1919 uiprogramsettings.cbPalette->setCurrentIndex(uiprogramsettings.cbPalette->count()-1);
1920 }
1921 }
1922 connect(uiprogramsettings.cbPalette, SIGNAL(activated(QString)), SLOT(setPalette(QString)));
1923
1924
1925
1926 QStringList mflist=_mainFont.toString().split(",", QString::SkipEmptyParts);
1927 uiprogramsettings.lbMainFontInfo->setText(trUtf8(" Font: ")+mflist.at(0)+trUtf8(" Size: ")+mflist.at(1));
1928 connect(uiprogramsettings.btnMainFont, SIGNAL(clicked()),SLOT(setMainFont()));
1929
1930 setLabelColor(uiprogramsettings.lbMiniMapRect, MiniMapRectColor);
1931 connect(uiprogramsettings.btnMiniMapRect, SIGNAL(clicked()), SLOT(setMiniMapRectColor()));
1932
1933 uiprogramsettings.cbTheme->setCurrentIndex(uiprogramsettings.cbTheme->findText(Theme::currentTheme().name(),Qt::MatchExactly));
1934 connect(uiprogramsettings.cbTheme,SIGNAL(activated(QString)),SLOT(setTheme(QString)));
1935
1936
1937 QSettings rsettings(QApplication::organizationName(), QApplication::applicationName());
1938 QString style = rsettings.value("style").value<QString>();
1939 uiprogramsettings.cbStyle->setCurrentIndex(uiprogramsettings.cbStyle->findText(style));
1940 connect(uiprogramsettings.cbStyle, SIGNAL(activated(QString)), SLOT(setStyle(QString)));
1941
1942 programsettingsWindow->show();
1943 }
1944
1945
1946
1947
printCrosti(QPrinter * printer)1948 void MainWindow::printCrosti(QPrinter *printer)
1949 {
1950 if(!printer->isValid()){
1951 Info::messageSplash(Info::msgPrinterNotFound);
1952 return;
1953 }
1954 int w=printer->pageRect().width();
1955 int h=printer->pageRect().height();
1956 if(!w || !h){
1957 Info::messageSplash(Info::msgPrintAreaError);
1958 return;
1959 }
1960
1961 QPainter p;
1962
1963 if(!p.begin(printer)){
1964 Info::messageSplash(Info::msgPrinterError);
1965 return;
1966 }
1967
1968 //crostiScene->render(&p);
1969 crostiViewer->scene()->render(&p);
1970 p.end();
1971 }
1972
1973
1974
printImage(QPrinter * printer)1975 void MainWindow::printImage(QPrinter *printer)
1976 {
1977 if(!printer->isValid()){
1978 Info::messageSplash(Info::msgPrinterNotFound);
1979 return;
1980 }
1981 int w=printer->pageRect().width();
1982 int h=printer->pageRect().height();
1983 if(!w || !h){
1984 Info::messageSplash(Info::msgPrintAreaError);
1985 return;
1986 }
1987
1988 QPainter p;
1989 if(!p.begin(printer)){
1990 Info::messageSplash(Info::msgPrinterError);
1991 return;
1992 }
1993
1994
1995 //imageScene->render(&p);
1996 imageViewer->scene()->render(&p);
1997 p.end();
1998 _picturePath=QFileInfo(printer->outputFileName()).canonicalPath();
1999 }
2000
2001
printScheme(QPrinter * printer)2002 void MainWindow::printScheme(QPrinter *printer)
2003 {
2004
2005 if(!printer->isValid()){
2006 Info::messageSplash(Info::msgPrinterNotFound);
2007 return;
2008 }
2009
2010 int pix=int(view->squarePix()*view->scale());//Масштабированный размер спрайта (в пикселах)
2011 int w=printer->pageRect().width()-2*view->dx();
2012 int h=printer->pageRect().height()-2*view->dx();
2013 if((w<=0)||(h<=0)){
2014 Info::messageSplash(Info::msgPrintAreaError);
2015 return;
2016 }
2017
2018 int countW=w;
2019 int countH=h;
2020 if(pix>0){
2021 countW/=pix;//Количество спрайтов умещающихся в ширине страницы принтера
2022 countH/=pix;//Количество спрайтов умещающихся в высоте страницы принтера
2023 }
2024
2025
2026 QSize sz=view->schemeSize()*pix;
2027 float scaleW=sz.width()/w;
2028 float scaleH=sz.height()/h;
2029
2030 qreal msize=(countW+1)*(countH+1)*qPow(view->squarePix()*view->scale(),2)*4;//Размер картинки в байтах
2031
2032
2033 QPainter p;
2034 if(!p.begin(printer)){
2035 Info::messageSplash(Info::msgPrinterError);
2036 return;
2037 }
2038
2039 //---Это усложнение нужно чтобы исключить создание пустых страниц, если sz.width()%w малое число.
2040 int modw=sz.width()%w;
2041 int modh=sz.height()%h;
2042 if(modw>2*view->dx())modw=scaleW+1;else modw=scaleW;
2043 if(modh>2*view->dx())modh=scaleH+1;else modh=scaleH;
2044 //-----------------------------------------------------------------------------
2045 int sz1=modw*modh;
2046 int counter=0;
2047 QString msg=trUtf8("Scheme is preparing for print. Please, wait...");
2048 statusBar()->showMessage(msg);
2049
2050 for(int j=0;j<modw;j++){
2051 for(int i=0;i<modh;i++){
2052 if(!isMemoryAvailable(msize)){
2053 p.end();
2054 statusBar()->showMessage(msg+" "+QString::number(counter+1)+"/"+QString::number(sz1),1e5);
2055 Info::messageSplash(Info::msgOutOfMemory);
2056 return;
2057 }
2058 counter++;
2059 p.drawImage(QPoint(0,0),view->toImage(QRect(j*countW,i*countH,countW+1,countH+1)));
2060 if(i<modh-1)printer->newPage();
2061 }
2062 if(j<modw-1)printer->newPage();
2063 statusBar()->showMessage(msg+" "+QString::number(counter)+"/"+QString::number(sz1),1e5);
2064 }
2065 p.end();
2066 statusBar()->showMessage("");
2067 }
2068
2069
2070
printColorTable(QPrinter * printer)2071 void MainWindow::printColorTable(QPrinter *printer)
2072 {
2073 if(!printer->isValid()){
2074 Info::messageSplash(Info::msgPrinterNotFound);
2075 return;
2076 }
2077
2078 int w=printer->pageRect().width();
2079 int h=printer->pageRect().height();
2080 if(!w || !h){
2081 Info::messageSplash(Info::msgPrintAreaError);
2082 return;
2083 }
2084
2085 QPainter p;
2086
2087 if(!p.begin(printer)){
2088 Info::messageSplash(Info::msgPrinterError);
2089 return;
2090 }
2091
2092
2093 //colorScene->render(&p);
2094 colorViewer->scene()->render(&p);
2095 p.end();
2096 }
2097
2098
2099
printDialog()2100 void MainWindow::printDialog()
2101 {
2102 QSettings rsettings(QApplication::organizationName(),QApplication::applicationName());
2103 QPrinter printer(QPrinter::ScreenResolution);
2104
2105 if(!rsettings.contains("printer"))
2106 rsettings.setValue("printer",printer.printerName());
2107 else printer.setPrinterName(rsettings.value("printer").value<QString>());
2108
2109 QPrintPreviewDialog *printPreview=new QPrintPreviewDialog(&printer);
2110 printPreview->setAttribute(Qt::WA_DeleteOnClose);
2111 printPreview->setWindowIcon(QIcon(Info::dataPath()+"/system/image/crosti.png"));
2112
2113
2114 switch(ui.tabWidget->currentIndex()){
2115 case 0:{
2116 printPreview->setWindowTitle(trUtf8("Preview picture"));
2117 connect(printPreview,SIGNAL(paintRequested(QPrinter*)),SLOT(printImage(QPrinter*)));
2118 }break;
2119 case 1:{
2120 printPreview->setWindowTitle(trUtf8("Preview - [Scheme: ")+_schemeName+"]");
2121 connect(printPreview,SIGNAL(paintRequested(QPrinter*)),SLOT(printScheme(QPrinter*)));
2122 }break;
2123 case 2:{
2124 printPreview->setWindowTitle(trUtf8("Preview - [Palette: ")+_schemeName+"]");
2125 connect(printPreview,SIGNAL(paintRequested(QPrinter*)),SLOT(printColorTable(QPrinter*)));
2126 }break;
2127 case 3:{
2128 printPreview->setWindowTitle(trUtf8("Preview cross stitch"));
2129 connect(printPreview,SIGNAL(paintRequested(QPrinter*)),SLOT(printCrosti(QPrinter*)));
2130 }break;
2131 }
2132
2133 if(printPreview->exec()==QDialog::Accepted)rsettings.setValue("printer",printer.printerName());
2134 }
2135
2136 /*
2137 void MainWindow::wheelEvent(QWheelEvent *e)
2138 {
2139 if(e->modifiers().testFlag(Qt::ControlModifier)){
2140 //e->delta() = +/- 120 см. мануал
2141 const char div=12;
2142 QSpinBox* sb=findChild<QSpinBox*>("scaleSB"+QString::number(ui.tabWidget->currentIndex()));
2143 if(sb!=NULL)sb->stepBy(int(e->delta()/div));
2144 }else{
2145 //wheelEvent(event);
2146 }
2147 }
2148 */
2149
2150
closeEvent(QCloseEvent * e)2151 void MainWindow::closeEvent(QCloseEvent *e)
2152 {
2153 /*
2154 if(_isSchemeUpdated){
2155 int ret=QMessageBox::question(this,QApplication::applicationName(),
2156 trUtf8("Scheme has changed. Save before exit?"),
2157 QMessageBox::Yes | QMessageBox::No
2158 | QMessageBox::Cancel,
2159 QMessageBox::Yes);
2160 switch(ret){
2161 case QMessageBox::Yes:{
2162 if(saveSchemeDialog()==QDialog::Rejected){
2163 e->ignore();
2164 return;
2165 }
2166 }
2167 break;
2168
2169 case QMessageBox::No:
2170 break;
2171
2172 case QMessageBox::Cancel:{
2173 e->ignore();
2174 return;
2175 }
2176 break;
2177
2178 }
2179
2180 }
2181 */
2182 if(!schemeSaveDialog()){
2183 e->ignore();
2184 return;
2185 }
2186
2187 QSettings rsettings(QApplication::organizationName(),QApplication::applicationName());
2188
2189 rsettings.setValue("language",_language);
2190
2191 rsettings.setValue("invertIcons",ui.chbInvert->isChecked());
2192 rsettings.setValue("showGrid",ui.chbGridShow->isChecked());
2193 rsettings.setValue("showIcons",ui.chbIconShow->isChecked());
2194 rsettings.setValue("showColors", ui.chbColorShow->isChecked());
2195
2196
2197 if(programsettingsWindow!=NULL){
2198 rsettings.setValue("theme",uiprogramsettings.cbTheme->currentText());
2199 }
2200
2201
2202 rsettings.setValue("schemeFilter", ui.filterCb->currentIndex());
2203 rsettings.setValue("schemeSquare",ui.squareSB->value());
2204 rsettings.setValue("crostiSquare",ui.squareSB1->value());
2205 rsettings.setValue("schemeLine",ui.lineSB->value());
2206 rsettings.setValue("toolLine",ui.sbLineWidth->value());
2207 rsettings.setValue("toolLineMode",ui.cbLineMode->currentIndex());
2208 rsettings.setValue("crostiLine",ui.lineSB1->value());
2209 rsettings.setValue("crostiDl",ui.dlSB->value());
2210 rsettings.setValue("crostiColor",_bkColor);
2211 rsettings.setValue("picturePath",_picturePath);
2212 rsettings.setValue("schemePath",_schemePath);
2213
2214 rsettings.setValue("windowGeometry",saveGeometry());
2215 rsettings.setValue("windowState",saveState());
2216
2217 e->accept();
2218 qApp->quit();
2219 }
2220
2221
wizardDialog()2222 void MainWindow::wizardDialog()
2223 {
2224 wizard->restart();
2225 wizard->show();
2226 }
2227
wizardAccepted()2228 void MainWindow::wizardAccepted()
2229 {
2230 colorTable.clear();
2231 colorCount.clear();
2232 colorTable<<wizard->colorTable;
2233 colorCount<<wizard->colorCount;
2234 _isConverted=true;
2235 _image=wizard->imageOriginal();
2236 _imageEtalon=_image;
2237 showImage(wizard->image());
2238 schemeBtnPress();
2239
2240 QSettings rsettings(QApplication::organizationName(),QApplication::applicationName());
2241 _picturePath=rsettings.value("picturePath").value<QString>();
2242
2243 ui.dwImage->setEnabled(true);
2244 }
2245
2246
createActions()2247 void MainWindow::createActions()
2248 {
2249
2250 openActionGroup=new QActionGroup(this);
2251 QSettings rsettings(QApplication::organizationName(),QApplication::applicationName());
2252 QString recentFiles=rsettings.value("recentFiles").value<QString>();
2253 QStringList recentFile=recentFiles.split(";",QString::SkipEmptyParts);
2254 for(int i=0;i<recentFile.size();i++){
2255 QFileInfo fi(recentFile.at(i));
2256 QAction *openAct=new QAction(QString::number(i+1)+" "+fi.fileName(),this);
2257 openAct->setData(fi.absoluteFilePath());
2258 openAct->setStatusTip(trUtf8("Open file: ")+fi.absoluteFilePath());
2259 openAct->setShortcut(tr("Alt+")+QString::number(i+1));
2260 openActionGroup->addAction(openAct);
2261 }
2262 connect(openActionGroup,SIGNAL(triggered(QAction*)),SLOT(openFile(QAction*)));
2263
2264
2265
2266 windowActionGroup=new QActionGroup(this);
2267
2268
2269 for(int i=0;i<ui.tabWidget->count();i++){
2270 QAction *windowAct=new QAction(ui.tabWidget->tabText(i),this);
2271 windowAct->setStatusTip(trUtf8("Jump to: ")+ui.tabWidget->tabText(i));
2272 windowAct->setIcon(QIcon(Info::dataPath()+"/system/image/"+QString::number(i+1)+".png"));
2273 windowAct->setData(i);
2274 windowAct->setShortcut(tr("Ctrl+")+QString::number(i+1));
2275 windowActionGroup->addAction(windowAct);
2276 }
2277 connect(windowActionGroup,SIGNAL(triggered(QAction*)),SLOT(openTab(QAction*)));
2278
2279 previewAct=new QAction(QIcon(Info::dataPath()+"/system/image/preview.png"),trUtf8("Preview..."),this);
2280 previewAct->setShortcut(tr("Ctrl+F"));
2281 connect(previewAct,SIGNAL(triggered()),SLOT(preview()));
2282
2283 wizardAct=new QAction(trUtf8("Wizard..."),this);
2284 wizardAct->setShortcut(tr("Ctrl+W"));
2285
2286 wizardAct->setIcon(QIcon(Info::dataPath()+"/system/image/wizard.png"));
2287 connect(wizardAct,SIGNAL(triggered()),this,SLOT(wizardDialog()));
2288
2289 openAct=new QAction(trUtf8("Open..."),this);
2290 openAct->setShortcut(tr("Ctrl+O"));
2291 openAct->setIcon(QIcon(Info::dataPath()+"/system/image/imageopen.png"));
2292 connect(openAct,SIGNAL(triggered()),this,SLOT(openDialog()));
2293
2294 exportAct=new QAction(trUtf8("Export..."),this);
2295 exportAct->setShortcut(tr("Ctrl+E"));
2296 exportAct->setIcon(QIcon(Info::dataPath()+"/system/image/export.png"));
2297 connect(exportAct,SIGNAL(triggered()),this,SLOT(exportDialog()));
2298
2299 saveAct=new QAction(trUtf8("Save"),this);
2300 saveAct->setShortcut(tr("Ctrl+S"));
2301 saveAct->setIcon(QIcon(Info::dataPath()+"/system/image/imagesave.png"));
2302 connect(saveAct,SIGNAL(triggered()),this,SLOT(saveDialog()));
2303
2304
2305 printAct=new QAction(trUtf8("Print..."),this);
2306 printAct->setShortcut(tr("Ctrl+P"));
2307 printAct->setIcon(QIcon(Info::dataPath()+"/system/image/print.png"));
2308
2309 connect(printAct,SIGNAL(triggered()),this,SLOT(printDialog()));
2310
2311 undoAct=new QAction(trUtf8("Undo"),this);
2312 undoAct->setShortcut(tr("Ctrl+Z"));
2313 undoAct->setEnabled(false);
2314 undoAct->setIcon(QIcon(Info::dataPath()+"/system/image/undo.png"));
2315 connect(undoAct, SIGNAL(triggered()), view, SLOT(undo()));
2316 connect(undoAct,SIGNAL(triggered()),SLOT(colorTableCreate()));
2317 connect(&view->history,SIGNAL(undoEnable(bool)),undoAct,SLOT(setEnabled(bool)));
2318
2319 redoAct=new QAction(trUtf8("Redo"),this);
2320 redoAct->setShortcut(tr("Shift+Ctrl+Z"));
2321 redoAct->setEnabled(false);
2322 redoAct->setIcon(QIcon(Info::dataPath()+"/system/image/redo.png"));
2323 connect(redoAct, SIGNAL(triggered()), view, SLOT(redo()));
2324 connect(redoAct,SIGNAL(triggered()),SLOT(colorTableCreate()));
2325 connect(&view->history,SIGNAL(redoEnable(bool)),redoAct,SLOT(setEnabled(bool)));
2326
2327 dwImageAct=new QAction(trUtf8("Picture"),this);
2328 dwImageAct->setShortcut(tr("F5"));
2329 dwImageAct->setCheckable(true);
2330 dwImageAct->setChecked(ui.dwImage->isVisible());
2331 dwImageAct->setIcon(ui.dwImage->windowIcon());
2332 connect(dwImageAct,SIGNAL(triggered(bool)),ui.dwImage,SLOT(setVisible(bool)));
2333 connect(ui.dwImage,SIGNAL(visibilityChanged(bool)),dwImageAct,SLOT(setChecked(bool)));
2334
2335 dwCrostiAct=new QAction(trUtf8("Cross stitch"),this);
2336 dwCrostiAct->setShortcut(tr("F7"));
2337 dwCrostiAct->setCheckable(true);
2338 dwCrostiAct->setChecked(ui.dwCrosti->isVisible());
2339 dwCrostiAct->setIcon(ui.dwCrosti->windowIcon());
2340 connect(dwCrostiAct,SIGNAL(triggered(bool)),ui.dwCrosti,SLOT(setVisible(bool)));
2341 connect(ui.dwCrosti,SIGNAL(visibilityChanged(bool)),dwCrostiAct,SLOT(setChecked(bool)));
2342
2343 dwPaletteAct=new QAction(trUtf8("Palette"),this);
2344 dwPaletteAct->setShortcut(tr("F6"));
2345 dwPaletteAct->setCheckable(true);
2346 dwPaletteAct->setChecked(ui.dwPalette->isVisible());
2347 dwPaletteAct->setIcon(ui.dwPalette->windowIcon());
2348 connect(dwPaletteAct,SIGNAL(triggered(bool)),ui.dwPalette,SLOT(setVisible(bool)));
2349 connect(ui.dwPalette,SIGNAL(visibilityChanged(bool)),dwPaletteAct,SLOT(setChecked(bool)));
2350
2351 dwToolAct=new QAction(trUtf8("Tools"),this);
2352 dwToolAct->setShortcut(tr("F8"));
2353 dwToolAct->setCheckable(true);
2354 dwToolAct->setChecked(ui.dwTool->isVisible());
2355 dwToolAct->setIcon(ui.dwTool->windowIcon());
2356 connect(dwToolAct,SIGNAL(triggered(bool)),ui.dwTool,SLOT(setVisible(bool)));
2357 connect(ui.dwTool,SIGNAL(visibilityChanged(bool)),dwToolAct,SLOT(setChecked(bool)));
2358
2359 dwMiniMapAct=new QAction(trUtf8("Minimap"),this);
2360 dwMiniMapAct->setShortcut(tr("F9"));
2361 dwMiniMapAct->setCheckable(true);
2362 dwMiniMapAct->setChecked(ui.dwMiniMap->isVisible());
2363 dwMiniMapAct->setIcon(ui.dwMiniMap->windowIcon());
2364 connect(dwMiniMapAct,SIGNAL(triggered(bool)),ui.dwMiniMap,SLOT(setVisible(bool)));
2365 connect(ui.dwMiniMap,SIGNAL(visibilityChanged(bool)),dwMiniMapAct,SLOT(setChecked(bool)));
2366
2367 exitAct = new QAction(trUtf8("Exit"), this);
2368 exitAct->setShortcut(tr("Ctrl+Q"));
2369 exitAct->setIcon(QIcon(Info::dataPath()+"/system/image/exit.png"));
2370 exitAct->setStatusTip(trUtf8("Exit program"));
2371 connect(exitAct,SIGNAL(triggered()),SLOT(close()));
2372
2373
2374 Info *out=new Info;
2375 aboutAct=new QAction(trUtf8("About..."), this);
2376 aboutAct->setIcon(QIcon(Info::dataPath()+"/system/image/crosti.png"));
2377 connect(aboutAct,SIGNAL(triggered()),out,SLOT(about()));
2378
2379 aboutQtAct=new QAction(trUtf8("About Qt..."), this);
2380 connect(aboutQtAct,SIGNAL(triggered()),out,SLOT(aboutQt()));
2381
2382 websiteAct=new QAction(trUtf8("Visit website..."), this);
2383 connect(websiteAct,SIGNAL(triggered()),out,SLOT(websiteVisit()));
2384
2385
2386 viewsettingAct= new QAction(trUtf8("Settings..."), this);
2387 viewsettingAct->setIcon(QIcon(Info::dataPath()+"/system/image/settings.png"));
2388 connect(viewsettingAct, SIGNAL(triggered()), this, SLOT(viewProgramSettings()));
2389 }
2390
2391
createMenus()2392 void MainWindow::createMenus()
2393 {
2394 menuBar()->setStyleSheet(Theme::currentTheme().menuStyle());
2395
2396 menuBar()->clear();
2397 menuBar()->setFont(_mainFont);
2398 fileMenu=menuBar()->addMenu(trUtf8("File"));
2399
2400 fileMenu->addAction(openAct);
2401 fileMenu->addAction(saveAct);
2402 fileMenu->addAction(exportAct);
2403 fileMenu->addSeparator();
2404 fileMenu->addAction(printAct);
2405 fileMenu->addSeparator();
2406 fileMenu->addAction(wizardAct);
2407 fileMenu->addSeparator();
2408
2409 for(int i=0;i<openActionGroup->actions().size();i++)
2410 fileMenu->addAction(openActionGroup->actions()[i]);
2411
2412 if(openActionGroup->actions().size()>0)fileMenu->addSeparator();
2413
2414 fileMenu->addAction(exitAct);
2415
2416
2417 viewMenu=menuBar()->addMenu(trUtf8("Edit"));
2418 viewMenu->addAction(undoAct);
2419 viewMenu->addAction(redoAct);
2420
2421
2422 viewMenu=menuBar()->addMenu(trUtf8("Tools"));
2423 viewMenu->addAction(dwImageAct);
2424 viewMenu->addAction(dwPaletteAct);
2425 viewMenu->addAction(dwCrostiAct);
2426 viewMenu->addAction(dwToolAct);
2427 viewMenu->addAction(dwMiniMapAct);
2428 viewMenu->addSeparator();
2429 viewMenu->addAction(viewsettingAct);
2430
2431
2432 viewMenu=menuBar()->addMenu(trUtf8("Window"));
2433 for(int i=0;i<windowActionGroup->actions().size();i++)
2434 viewMenu->addAction(windowActionGroup->actions()[i]);
2435 viewMenu->addSeparator();
2436 viewMenu->addAction(previewAct);
2437
2438
2439 helpMenu = menuBar()->addMenu(trUtf8("Help"));
2440 helpMenu->addAction(aboutQtAct);
2441 helpMenu->addAction(aboutAct);
2442 helpMenu->addSeparator();
2443 helpMenu->addAction(websiteAct);
2444 }
2445
2446
showImage(QImage img)2447 void MainWindow::showImage(QImage img)
2448 {
2449
2450 imageViewer->setImage(img);
2451
2452
2453 //ui.tabWidget->setCurrentIndex(0);
2454 imgH=img.height();
2455 imgW=img.width();
2456
2457
2458 ui.dwImage->setEnabled(true);
2459 ui.widthSB->setValue(img.width());
2460 ui.heightSB->setValue(img.height());
2461
2462 imageSizeShow(img);
2463
2464
2465 setCurrentTab(0);
2466 }
2467
2468
setCurrentTab(int index)2469 void MainWindow::setCurrentTab(int index)
2470 {
2471 if (ui.tabWidget->currentIndex() == index)
2472 updateTab(index);
2473 else
2474 ui.tabWidget->setCurrentIndex(index);
2475 }
2476
2477
saveRegistry(QFileInfo fi)2478 void MainWindow::saveRegistry(QFileInfo fi)
2479 {
2480 const int recentFilesCount=9;
2481
2482 //Добавление открытого файла в реестр
2483 QSettings rsettings(QApplication::organizationName(),QApplication::applicationName());
2484 QString recentFiles=rsettings.value("recentFiles").value<QString>();
2485 QStringList recentFile=recentFiles.split(";",QString::SkipEmptyParts);
2486
2487 bool isPresent=false;
2488 for(int i=0;i<recentFile.size();i++)
2489 if(fi.absoluteFilePath()==recentFile.at(i)){
2490 isPresent=true;
2491 break;
2492 }
2493 if(!isPresent)recentFile.append(fi.absoluteFilePath());
2494 if(recentFile.size()>recentFilesCount)recentFile.removeFirst();
2495
2496
2497 recentFiles="";
2498 for(int i=0;i<recentFile.size();i++)recentFiles+=recentFile.at(i)+";";
2499
2500 rsettings.setValue("recentFiles",recentFiles);
2501 //------------------------------------------------------------------------------
2502 }
2503
2504
openFile(QAction * act)2505 void MainWindow::openFile(QAction *act)
2506 {
2507 QFileInfo fi(act->data().toString());
2508
2509 if(fi.suffix()=="cst")
2510 if(schemeSaveDialog())openScheme(fi.absoluteFilePath());else return;
2511 else
2512 openImage(fi.absoluteFilePath());
2513 }
2514
2515
openTab(QAction * act)2516 void MainWindow::openTab(QAction *act)
2517 {
2518 //ui.tabWidget->setCurrentIndex(act->data().toInt());
2519 setCurrentTab(act->data().toInt());
2520 }
2521
2522
2523
2524
openImage(QString fileName)2525 void MainWindow::openImage(QString fileName)
2526 {
2527 if(_image.load(fileName)){
2528
2529 if(!_image.isNull()){
2530 _imageEtalon=_image;
2531 _imageName=fileName;
2532 _angle=0;
2533
2534
2535 saveRegistry(QFileInfo(fileName));
2536
2537 colorCount.clear();
2538
2539 ui.colorSB->setMaximum(256);
2540 setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Picture: ")+_imageName+"]");
2541 showImage(_image);
2542
2543 _isConverted=false;
2544 //_isSchemeCreated=false;
2545 _picturePath=QFileInfo(fileName).canonicalPath();
2546 }else Info::message(trUtf8("The picture has no data %1.").arg(fileName));
2547 }else Info::message(trUtf8("Can't open the picture %1.").arg(fileName));
2548 }
2549
2550
2551
openDialog()2552 void MainWindow::openDialog()
2553 {
2554 QStringList filters = QStringList() <<
2555 Info::imageFilter(QImageReader::supportedImageFormats()) <<
2556 trUtf8("Crosti design (*.cst)") <<
2557 trUtf8("Any file (*)");
2558
2559 QString filter="";
2560 QString directory=Info::dataPath();
2561 int tabid=ui.tabWidget->currentIndex();
2562
2563
2564 const QString SEP = ";;";
2565 if((tabid==1)||(tabid==2)){
2566 filter = QString("%2%1%3%1%4").arg(SEP, filters.at(1), filters.at(0), filters.at(2));
2567 directory=_schemePath;
2568 }else{
2569 filter = QString("%2%1%3%1%4").arg(SEP, filters.at(0), filters.at(1), filters.at(2));
2570 directory=_picturePath;
2571 }
2572
2573
2574 QFileDialog *openDialog=new QFileDialog(this,trUtf8("Open file"),directory,filter);
2575 openDialog->setAcceptMode(QFileDialog::AcceptOpen);
2576 openDialog->setFileMode(QFileDialog::AnyFile);
2577 if(openDialog->exec()){
2578 QString fileName=openDialog->selectedFiles().at(0);
2579 switch(analyzeSuffix(QFileInfo(fileName).suffix())){
2580 //Рисунки
2581 case 0:{
2582 openImage(fileName);
2583 _picturePath=QFileInfo(fileName).canonicalPath();
2584 };break;
2585 //cst
2586 case 1:{
2587 openScheme(fileName);
2588 _schemePath=QFileInfo(fileName).canonicalPath();
2589 };break;
2590 }
2591 }
2592 }
2593
2594
saveImageDialog()2595 void MainWindow::saveImageDialog()
2596 {
2597 //if(imageScene->items().size()!=0){
2598 if(imageViewer->scene()->items().size()!=0){
2599
2600 QString filter=Info::imageFilter(QImageWriter::supportedImageFormats())+";;"+trUtf8("Portable document file (*.pdf)");
2601 QFileDialog *saveDialog=new QFileDialog(this,trUtf8("Save picture"),_picturePath,filter);
2602
2603 saveDialog->setAcceptMode(QFileDialog::AcceptSave);
2604 saveDialog->setFileMode(QFileDialog::AnyFile);
2605 if(saveDialog->exec()){
2606 QString fileName=saveDialog->selectedFiles().at(0);
2607 checkSuffix(&fileName,saveDialog->selectedNameFilter());
2608 switch(analyzeSuffix(QFileInfo(fileName).suffix())){
2609 //Рисунки
2610 case 0:{
2611 //QPixmap pix=renderPixmap(imageScene);
2612 //bool saved=pix.save(fileName,0,100);
2613 bool saved=imageViewer->image().save(fileName,0,100);
2614 if(saved)
2615 openImage(fileName);
2616 else
2617 Info::messageSplash(Info::msgImageSaveError);
2618 };break;
2619
2620 //pdf
2621 case 2:{
2622 QPrinter printerPDF(QPrinter::ScreenResolution);
2623 printerPDF.setOutputFormat(QPrinter::PdfFormat);
2624 printerPDF.setOutputFileName(fileName);
2625 printImage(&printerPDF);
2626 };break;
2627 }
2628 }
2629 }else
2630 Info::messageSplash(trUtf8("Nothing to save - picture isn't open!"));
2631
2632 }
2633
saveColorTableDialog()2634 void MainWindow::saveColorTableDialog()
2635 {
2636 //if(colorScene->items().size()!=0){
2637 if(colorViewer->scene()->items().size()!=0){
2638 QString fileName=QFileDialog::getSaveFileName(this,trUtf8("Save palette"),_picturePath,Info::imageFilter(QImageWriter::supportedImageFormats()));
2639 //QPixmap pix=renderPixmap(colorScene);
2640 //bool saved=pix.save(fileName,0,100);
2641 bool saved=colorViewer->image().save(fileName,0,100);
2642 if(saved)
2643 _picturePath=QFileInfo(fileName).canonicalPath();
2644 else
2645 Info::messageSplash(Info::msgImageSaveError);
2646 }else
2647 Info::messageSplash(trUtf8("Nothing to save - palette is not set!"));
2648 }
2649
saveCrostiDialog()2650 void MainWindow::saveCrostiDialog()
2651 {
2652 //if(crostiScene->items().size()!=0){
2653 if(crostiViewer->scene()->items().size()!=0){
2654 QString fileName=QFileDialog::getSaveFileName(this,trUtf8("Save cross stitch"),_picturePath,Info::imageFilter(QImageWriter::supportedImageFormats()));
2655
2656 //QPixmap pix=renderPixmap(crostiScene);
2657 //bool saved=pix.save(fileName,0,100);
2658 bool saved=crostiViewer->image().save(fileName,0,100);
2659 if(saved){
2660 _crostiName=fileName;
2661 _picturePath=QFileInfo(fileName).canonicalPath();
2662 setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Cross stitch: ")+_crostiName+"]");
2663 }else
2664 Info::messageSplash(Info::msgImageSaveError);
2665
2666 }else
2667 Info::messageSplash(trUtf8("Nothing to save - cross stitch is not set!"));
2668 }
2669
2670
2671
openScheme(QString fileName)2672 void MainWindow::openScheme(QString fileName)
2673 {
2674 if(!fileName.isEmpty()){
2675 square=0;
2676 int line=0;
2677 bool isOk=true;
2678 QString path=fileName;
2679 QFile file(path);
2680
2681
2682 if(file.open(QIODevice::ReadOnly|QIODevice::Text)){
2683 colorTable.clear();
2684 id.clear();
2685 QTextStream in(&file);
2686 QString initStr=in.readLine();
2687 bool colorTableLoad=false;
2688
2689
2690 QRegExp rx("#COLOR TABLE:?\\s*(\\w*)");
2691 if (rx.indexIn(initStr, 0) != -1) {
2692 colorTableLoad = true;
2693 QString paletteName = (rx.cap(1).isEmpty()) ?
2694 "dmc" :
2695 rx.cap(1);
2696 paletteOpen(paletteName);
2697 } else
2698 isOk = false;
2699
2700
2701 if (isOk)
2702 while(!in.atEnd()){
2703 QString str="";
2704
2705 while((str.isEmpty())&&(!in.atEnd()))str=in.readLine();
2706
2707 if(str=="#SCHEME CONTENT"){
2708 str="";
2709 while((str.isEmpty())&&(!in.atEnd()))str=in.readLine();
2710 colorTableLoad=false;
2711 QStringList infoList=str.split(" ",QString::SkipEmptyParts);
2712 if(infoList.size()>=4){
2713 imgW=infoList.at(0).toInt(&isOk);
2714 if(!isOk)break;
2715 imgH=infoList.at(1).toInt(&isOk);
2716 if(!isOk)break;
2717 square=infoList.at(2).toInt(&isOk);
2718 if(!isOk)break;
2719 line=infoList.at(3).toInt(&isOk);
2720 if(!isOk)break;
2721
2722 if(infoList.size()>=5){
2723 _bkColor=QColor(infoList.at(4).toUInt(&isOk));
2724 if(!isOk)break;
2725 }
2726 }else isOk=false;
2727 break;
2728 }
2729
2730
2731 QStringList strList=str.split(" ");
2732 if(colorTableLoad){
2733 colorTable.append(strList.at(0).toUInt(&isOk));
2734 if(!isOk)break;
2735 if(strList.size()==2){
2736 id.append(strList.at(1).toInt(&isOk));
2737 if(!isOk)break;
2738 }
2739 }
2740 }
2741 file.close();
2742 }else{
2743 Info::message(trUtf8("File not found! - ")+path);
2744 return;
2745 }
2746
2747
2748 if(isOk){
2749 saveRegistry(QFileInfo(fileName));
2750
2751 ui.squareSB->setValue(square);
2752 ui.lineSB->setValue(line);
2753 //ui.dwImage->setEnabled(false);
2754
2755 //imageViewer->scene()->clear();
2756 //crostiViewer->scene()->clear();
2757 crostiClear();
2758
2759 _isColorTableUpdated=false;
2760 _isSchemeUpdated=false;
2761
2762 schemeFromFile(fileName);
2763 schemeCreate();
2764
2765 setBackground(_bkColor);
2766
2767 _schemeName=fileName;
2768 setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Design: ")+_schemeName+"]");
2769
2770 //ui.tabWidget->setCurrentIndex(1);
2771 setCurrentTab(1);
2772 }else Info::message(trUtf8("Can't open the design - wrong file format!"));
2773 }
2774 }
2775
2776
2777
saveDialog()2778 void MainWindow::saveDialog()
2779 {
2780 if((_schemeName==trUtf8("new"))||(_schemeName==""))
2781 saveSchemeDialog();
2782 else schemeSave(_schemeName);
2783 }
2784
2785
2786
exportDialog()2787 void MainWindow::exportDialog()
2788 {
2789 switch(ui.tabWidget->currentIndex()){
2790 case 0:{
2791 saveImageDialog();
2792 }break;
2793 case 1:{
2794 saveSchemeDialog();
2795 }break;
2796 case 2:{
2797 saveColorTableDialog();
2798 }break;
2799 case 3:{
2800 saveCrostiDialog();
2801 }break;
2802 }
2803 }
2804
2805
colorID(const QColor & cl) const2806 int MainWindow::colorID(const QColor& cl)const
2807 {
2808 for(int clId=0;clId<colorTable.size();clId++)
2809 if(cl==colorTable.at(clId))return clId;
2810 return 0;
2811 }
2812
2813
saveSchemeDialog()2814 QDialog::DialogCode MainWindow::saveSchemeDialog(){
2815 QDialog::DialogCode result=QDialog::Rejected;
2816 if(colorTable.size()){
2817 QString filter=trUtf8("Crosti design (*.cst);;Portable document file (*.pdf);;")+Info::imageFilter(QImageWriter::supportedImageFormats());
2818 QFileDialog *saveDialog=new QFileDialog(this,trUtf8("Save design"),_schemePath,filter);
2819 saveDialog->setAcceptMode(QFileDialog::AcceptSave);
2820 saveDialog->setFileMode(QFileDialog::AnyFile);
2821 saveDialog->selectFile(_schemeName);
2822 if(saveDialog->exec()){
2823 result=QDialog::Accepted;
2824 QString fileName=saveDialog->selectedFiles().at(0);
2825 checkSuffix(&fileName,saveDialog->selectedNameFilter());
2826 switch(analyzeSuffix(QFileInfo(fileName).suffix())){
2827 //Рисунки
2828 case 0:{
2829 statusBar()->showMessage(Info::message(Info::msgPleaseWait));
2830 bool saved=view->toImage(false).save(fileName,0,100);
2831 if(saved)
2832 _picturePath=QFileInfo(fileName).canonicalPath();
2833 else
2834 Info::messageSplash(Info::msgImageSaveError);
2835 statusBar()->clearMessage();
2836 };break;
2837 //cst
2838 case 1:{
2839 if(!schemeSave(fileName))
2840 return QDialog::Rejected;
2841 };break;
2842 //pdf
2843 case 2:{
2844 QPrinter printerPDF(QPrinter::ScreenResolution);
2845 printerPDF.setOutputFormat(QPrinter::PdfFormat);
2846 printerPDF.setOutputFileName(fileName);
2847 printScheme(&printerPDF);
2848 _picturePath=QFileInfo(fileName).canonicalPath();
2849 };break;
2850 }
2851 }
2852 }else Info::messageSplash(trUtf8("Nothing to save - the design isn't created!"));
2853 return result;
2854 }
2855
2856
2857
2858
schemeSave(QString fileName)2859 bool MainWindow::schemeSave(QString fileName)
2860 {
2861 QFile file(fileName);
2862 if(file.open(QIODevice::WriteOnly|QIODevice::Text)){
2863 QTextStream out(&file);
2864
2865 QString paletteName = ui.dwPalette->property("paletteName").toString();
2866
2867 out << "#COLOR TABLE: " << paletteName << endl;
2868 for(int i=0;i<colorTable.size();i++){
2869 int num=Sprite::NO_ICON;
2870 if(i<paletteModel->rowCount()){
2871 QModelIndex index=paletteModel->index(i,1);
2872 num=paletteModel->data(index,Qt::UserRole).toInt();
2873 }
2874 out<<colorTable.at(i)<<" "<<num<<endl;
2875 }
2876 out<<endl;
2877 out<<"#SCHEME CONTENT"<<endl;
2878 out<<view->schemeSize().width()<<" "<<view->schemeSize().height()<<" "<<ui.squareSB->value()<<" "<<ui.lineSB->value()<<" "<<_bkColor.rgb()<<endl;
2879
2880 int sz=view->spriteSize()+view->lineSize();
2881 int max=20;
2882 int pbdiv=sz/max;
2883 if(sz<max)pbdiv=1;
2884
2885
2886 progressDialog pb(trUtf8("Saving cross stitch"),trUtf8("Cancel"),0,max+1);
2887 pb.show();
2888
2889
2890 for(int i=0;i<view->spriteSize();i++){
2891 Sprite *sp=view->getSprite(i);
2892 int clId=colorID(sp->color());
2893
2894 //Цвет = _bkColor и iconID = INT_MAX определяют цвет фона.
2895 if((sp->color()==_bkColor)&&(sp->iconID()==INT_MAX))clId=-1;
2896
2897 int x=int((sp->pos().x()-view->dx())/view->squarePix());
2898 int y=int((sp->pos().y()-view->dx())/view->squarePix());
2899
2900 out<<x<<" "<<y<<" "<<clId;
2901 int stId=static_cast<int>(sp->stitch());
2902 if(stId!=0)out<<" "<<stId;
2903 out<<endl;
2904
2905 if(i%pbdiv==0)pb.addValue(1);
2906 if(pb.wasCanceled()){
2907 file.close();
2908 QFile::remove(fileName);
2909 return false;
2910 }
2911 }
2912 for(int i=0;i<view->lineSize();i++){
2913 Line* ln=view->getLine(i);
2914 int clId=colorID(ln->color());
2915 out<<*ln<<" "<<clId<<endl;
2916
2917 if(i%pbdiv==0)pb.addValue(1);
2918 if(pb.wasCanceled()){
2919 file.close();
2920 QFile::remove(fileName);
2921 return false;
2922 }
2923 }
2924 file.close();
2925
2926 _isSchemeUpdated=false;
2927 _schemeName=fileName;
2928 _schemePath=QFileInfo(fileName).canonicalPath();
2929 saveRegistry(QFileInfo(_schemeName));
2930 setWindowTitle(QApplication::applicationName()+" - ["+trUtf8("Scheme: ")+_schemeName+"]");
2931 }else{
2932 Info::messageSplash(Info::msgSchemeSaveError);
2933 return false;
2934 }
2935
2936 return true;
2937 }
2938
2939
2940 /*
2941 void MainWindow::setScaleScheme(int factor)
2942 {
2943 view->setScale(qreal(factor)/100);
2944
2945 adjustScrollBar(ui.scrollArea1->horizontalScrollBar(),factor/100);
2946 adjustScrollBar(ui.scrollArea1->verticalScrollBar(),factor/100);
2947 }
2948
2949
2950 void MainWindow::setScaleColorTable(int factor)
2951 {
2952 ui.colorView->resetTransform();
2953 qreal scale=qreal(factor)/100;
2954 ui.colorView->scale(scale,scale);
2955 }
2956
2957
2958 void MainWindow::setScaleCrosti(int factor)
2959 {
2960 ui.crostiView->resetTransform();
2961 qreal scale=qreal(factor)/100;
2962 ui.crostiView->scale(scale,scale);
2963 }
2964
2965
2966 void MainWindow::setScaleImage(int factor)
2967 {
2968 ui.imageView->resetTransform();
2969 qreal scale=qreal(factor)/100;
2970 ui.imageView->scale(scale,scale);
2971 }
2972 */
2973 /*
2974 void MainWindow::scaleResetBtnPress()
2975 {
2976 ui.scaleSB0->setValue(100);
2977 }
2978 */
2979 /*
2980 void MainWindow::scaleResetBtn1Press()
2981 {
2982 ui.scaleSB1->setValue(100);
2983 }
2984 */
2985 /*
2986 void MainWindow::scaleResetBtn2Press()
2987 {
2988 ui.scaleSB2->setValue(100);
2989 }
2990
2991
2992 void MainWindow::scaleResetBtn3Press()
2993 {
2994 ui.scaleSB3->setValue(100);
2995 }
2996 */
2997
2998 /*
2999 void MainWindow::adjustScrollBar(QScrollBar *scrollBar,double factor)
3000 {
3001 scrollBar->setValue(int(factor*scrollBar->value()+((factor-1)*scrollBar->pageStep()/2)));
3002 }
3003 */
3004
setStyle(const QString & name)3005 void MainWindow::setStyle(const QString &name) {
3006 if (name == NO_STYLE)
3007 return;
3008 QApplication::setStyle(QStyleFactory::create(name));
3009 QSettings rsettings(QApplication::organizationName(), QApplication::applicationName());
3010 rsettings.setValue("style", name);
3011 }
3012
3013
setUnits(int id)3014 void MainWindow::setUnits(int id){
3015 _units=id;
3016 QSettings rsettings(QApplication::organizationName(),QApplication::applicationName());
3017 rsettings.setValue("units",_units);
3018 }
3019
3020
priceBtnPress()3021 void MainWindow::priceBtnPress()
3022 {
3023 float res = 0;
3024 float csprice = float(0.3);
3025
3026 res=imgW*imgH*csprice;
3027
3028 //Кц - количество цветов
3029 if(colorTable.size()>25)
3030 res+=(colorTable.size()-25)*res*0.01;
3031
3032
3033 //Цк - цвет канвы (вычисление компоненты Lightness формата HSL)
3034 if(lightness(_bkColor)<128)res+=res*0.25;
3035
3036 //Рк - размер канвы
3037 if(ui.squareSB1->value()>14)
3038 res+=res*(0.25-0.015*(ui.squareSB1->maximum()-ui.squareSB1->value()));
3039
3040
3041 //Рс - разработка схемы
3042 res+=0.3*res;
3043
3044
3045 int time=int(imgW*imgH/75);
3046 //Время вышивания
3047 Info::message(trUtf8("Cross stitch price: ")+QString::number(res)+trUtf8(" rub.")+"<br>"+
3048 trUtf8("Time to complete: ")+QString::number(time)+trUtf8(" h. / ")+
3049 QString::number(int(time/5))+trUtf8(" d."));
3050 }
3051
3052
random(int Max)3053 float MainWindow::random(int Max)
3054 {
3055 static bool firstTime = true;
3056 if(firstTime){
3057 firstTime = false;
3058 QTime midnight(0, 0, 0);
3059 srand(midnight.secsTo(QTime::currentTime()));
3060 }
3061 float res=0;
3062 res=rand()%1000;
3063 res/=1000;
3064 return res*Max;
3065 }
3066
3067
3068
lightness(QColor color)3069 float MainWindow::lightness(QColor color)
3070 {
3071 //Вычисление компоненты Lightness формата HSL
3072 QList<int>col;
3073 col.append(color.red());
3074 col.append(color.green());
3075 col.append(color.blue());
3076 for(int i=0;i<col.size();i++){
3077 int max=0;
3078 int num=0;
3079 for(int j=i;j<col.size();j++){
3080 if(col.at(j)>max){
3081 max=col.at(j);
3082 num=j;
3083 }
3084 }
3085 col.swap(i,num);
3086 }
3087
3088 return 0.5*(col.at(0)+col.at(col.size()-1));
3089 }
3090
3091