1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  TrenchBroom is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "ChoosePathTypeDialog.h"
21 
22 #include "IO/SystemPaths.h"
23 #include "View/ViewConstants.h"
24 #include "View/wxUtils.h"
25 
26 #include <wx/gbsizer.h>
27 #include <wx/panel.h>
28 #include <wx/radiobut.h>
29 #include <wx/stattext.h>
30 
31 namespace TrenchBroom {
32     namespace View {
IMPLEMENT_DYNAMIC_CLASS(ChoosePathTypeDialog,wxDialog)33         IMPLEMENT_DYNAMIC_CLASS(ChoosePathTypeDialog, wxDialog)
34 
35         ChoosePathTypeDialog::ChoosePathTypeDialog() :
36         wxDialog(NULL, wxID_ANY, "Path Type"),
37         m_absPath(""),
38         m_docRelativePath(""),
39         m_gameRelativePath(""),
40         m_appRelativePath("") {
41             Create();
42         }
43 
44 
ChoosePathTypeDialog(wxWindow * parent,const IO::Path & absPath,const IO::Path & docPath,const IO::Path & gamePath)45         ChoosePathTypeDialog::ChoosePathTypeDialog(wxWindow* parent, const IO::Path& absPath, const IO::Path& docPath, const IO::Path& gamePath) :
46         wxDialog(parent, wxID_ANY, "Path Type"),
47         m_absPath(absPath),
48         m_docRelativePath(makeRelativePath(absPath, docPath.deleteLastComponent())),
49         m_gameRelativePath(makeRelativePath(absPath, gamePath)),
50         m_appRelativePath(makeRelativePath(absPath, IO::SystemPaths::appDirectory())) {
51             Create();
52         }
53 
Create()54         bool ChoosePathTypeDialog::Create() {
55             wxPanel* panel = new wxPanel(this);
56             panel->SetBackgroundColour(*wxWHITE);
57 
58             wxStaticText* infoText = new wxStaticText(panel, wxID_ANY, "Paths can be stored either as absolute paths or as relative paths. Please choose how you want to store this path.");
59             infoText->Wrap(370);
60 
61             m_absRadio = new wxRadioButton(panel, wxID_ANY, "Absolute");
62             m_absRadio->SetFont(m_absRadio->GetFont().MakeBold());
63             m_absRadio->SetValue(true);
64             wxStaticText* absolutePathText = new wxStaticText(panel, wxID_ANY, m_absPath.asString(), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_MIDDLE);
65 
66             m_docRelativeRadio = new wxRadioButton(panel, wxID_ANY, "Relative to map file");
67             m_docRelativeRadio->SetFont(m_docRelativeRadio->GetFont().MakeBold());
68             if (m_docRelativePath.isEmpty())
69                 m_docRelativeRadio->Enable(false);
70             wxStaticText* mapRelativePathText = new wxStaticText(panel, wxID_ANY, m_docRelativePath.isEmpty() ? "Unable to build a path." : m_docRelativePath.asString(), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_MIDDLE);
71 
72             m_appRelativeRadio = new wxRadioButton(panel, wxID_ANY, "Relative to application executable");
73             m_appRelativeRadio->SetFont(m_appRelativeRadio->GetFont().MakeBold());
74             if (m_appRelativePath.isEmpty())
75                 m_appRelativeRadio->Enable(false);
76             wxStaticText* appRelativePathText = new wxStaticText(panel, wxID_ANY, m_appRelativePath.isEmpty() ? "Unable to build a path." : m_appRelativePath.asString(), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_MIDDLE);
77 
78             m_gameRelativeRadio = new wxRadioButton(panel, wxID_ANY, "Relative to game directory");
79             if (m_gameRelativePath.isEmpty())
80                 m_gameRelativeRadio->Enable(false);
81             m_gameRelativeRadio->SetFont(m_gameRelativeRadio->GetFont().MakeBold());
82             wxStaticText* gameRelativePathText = new wxStaticText(panel, wxID_ANY, m_gameRelativePath.isEmpty() ? "Unable to build a path." : m_gameRelativePath.asString(), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_MIDDLE);
83 
84 #if defined __APPLE__
85             absolutePathText->SetFont(*wxSMALL_FONT);
86             mapRelativePathText->SetFont(*wxSMALL_FONT);
87             appRelativePathText->SetFont(*wxSMALL_FONT);
88             gameRelativePathText->SetFont(*wxSMALL_FONT);
89 #endif
90 
91             wxGridBagSizer* innerSizer = new wxGridBagSizer();
92 
93             innerSizer->Add(infoText, wxGBPosition(0, 0), wxGBSpan(1, 2));
94             innerSizer->Add(1, 2 * LayoutConstants::WideVMargin, wxGBPosition(1,0), wxGBSpan(1,2));
95 
96             innerSizer->Add(m_absRadio, wxGBPosition(2, 0), wxGBSpan(1, 2));
97             innerSizer->Add(18, 1, wxGBPosition(3, 0), wxGBSpan(1, 1));
98             innerSizer->Add(absolutePathText, wxGBPosition(3, 1), wxGBSpan(1, 1));
99             innerSizer->Add(1, LayoutConstants::WideVMargin, wxGBPosition(4,0), wxGBSpan(1,2));
100 
101             innerSizer->Add(m_docRelativeRadio, wxGBPosition(5, 0), wxGBSpan(1, 2));
102             innerSizer->Add(18, 1, wxGBPosition(6, 0), wxGBSpan(1, 1));
103             innerSizer->Add(mapRelativePathText, wxGBPosition(6, 1), wxGBSpan(1, 1));
104             innerSizer->Add(1, LayoutConstants::WideVMargin, wxGBPosition(7,0), wxGBSpan(1,2));
105 
106             innerSizer->Add(m_appRelativeRadio, wxGBPosition(8, 0), wxGBSpan(1, 2));
107             innerSizer->Add(18, 1, wxGBPosition(9, 0), wxGBSpan(1, 1));
108             innerSizer->Add(appRelativePathText, wxGBPosition(9, 1), wxGBSpan(1, 1));
109             innerSizer->Add(1, LayoutConstants::WideVMargin, wxGBPosition(10,0), wxGBSpan(1,2));
110 
111             innerSizer->Add(m_gameRelativeRadio, wxGBPosition(11, 0), wxGBSpan(1, 2));
112             innerSizer->Add(18, 1, wxGBPosition(12, 0), wxGBSpan(1, 1));
113             innerSizer->Add(gameRelativePathText, wxGBPosition(12, 1), wxGBSpan(1, 1));
114 
115             wxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);
116             panelSizer->Add(innerSizer, 1, wxEXPAND | wxALL, LayoutConstants::DialogOuterMargin);
117             panel->SetSizerAndFit(panelSizer);
118 
119             wxSizer* buttonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
120             wxSizer* outerSizer = new wxBoxSizer(wxVERTICAL);
121             outerSizer->Add(panel, 1, wxEXPAND);
122             outerSizer->Add(wrapDialogButtonSizer(buttonSizer, this), 0, wxEXPAND);
123 
124             SetSizerAndFit(outerSizer);
125             CentreOnParent();
126             return true;
127        }
128 
path() const129         const IO::Path& ChoosePathTypeDialog::path() const {
130             if (m_docRelativeRadio->GetValue())
131                 return m_docRelativePath;
132             if (m_appRelativeRadio->GetValue())
133                 return m_appRelativePath;
134             if (m_gameRelativeRadio->GetValue())
135                 return m_gameRelativePath;
136             return m_absPath;
137         }
138 
makeRelativePath(const IO::Path & absPath,const IO::Path & newRootPath)139         IO::Path ChoosePathTypeDialog::makeRelativePath(const IO::Path& absPath, const IO::Path& newRootPath) {
140             if (!newRootPath.canMakeRelative(absPath))
141                 return IO::Path("");
142             return newRootPath.makeRelative(absPath);
143         }
144     }
145 }
146